You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译期比较不完全类型extern const变量指针是否符合C++标准?

编译期比较不完全类型extern const变量指针的标准合规性问题

问题代码示例

不完全类型场景

这段代码可被MSVC和Clang接受,但GCC 13.2及以后版本(含主干版)会报错:non-constant condition for static assertion

struct A;

extern const A a1;
extern const A a2;

static_assert(&a1 != &a2);

完整类型场景

如果struct A是完整类型,GCC及其他编译器均会接受该代码:

struct A;

struct A{};

extern const A a1;
extern const A a2;

static_assert(&a1 != &a2);

直觉与标准查阅分析

从逻辑上看,不完全类型的场景应该被支持——这里不需要编译器知晓对象的布局、成员或大小等细节。

查阅C++标准后,无法直接确定GCC的行为是否合规:

  1. C++20标准(N4860):
    该情况似乎不属于*[expr.const]*中规定的非核心常量表达式范畴,唯一相关条款为:

    表达式E是核心常量表达式,除非按照抽象机规则(6.9.1)求值时,会执行以下操作之一:
    ...
    (5.23) 结果未指定的三路比较(7.6.8)、关系(7.6.9)或相等(7.6.10)运算符
    ...
    找不到该比较结果未指定的依据。直觉上,两个不同名称的extern const对象在编译期会生成不同的重定位信息,后续由链接器处理。

  2. 最新C++标准草案:
    *[expr.const]*中新增了一项非核心常量表达式的情形:

    (2.28) 比较指向潜在非唯一对象的指针的相等运算符,若两个操作数的指针值关联不同求值过程(*[basic.compound]*),且二者均可指向同一潜在非唯一对象内的同一偏移,或其中一个指向类型具有constexpr-unknown表示的对象;
    其中定义的constexpr-unknown表示类型为:
    (1.1) union类型
    (1.2) 指针或成员指针类型
    (1.3) 带volatile限定符的类型
    (1.4) 包含引用类型非静态数据成员的类类型
    (1.5) 存在基类或非静态成员的类型具有constexpr-unknown表示
    讨论的案例不属于上述任何范畴,因此C++20/23/26中似乎对此无限制。

  3. 其他标准条款:

    • *[basic.link]*仅说明两个声明是否指向同一对象,未阐述两个extern const声明是否可能指向同一对象。
    • *[expr.eq]*也未提供与该问题相关的有用条款。

核心问题

  • 编译期比较不完全类型extern const变量的指针是否符合C++标准?即GCC拒绝上述代码是否正确?

内容的提问来源于stack exchange,提问作者kudiko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 00:00:26