繁体   English   中英

G ++ vs Clang:constexpr和const的行为不一致

[英]G++ vs Clang : inconsistent behavior for constexpr and const

考虑以下代码:

constexpr const int A = 42;

const int &B = A;
static_assert(&A == &B, "Bug");

constexpr const int &C = B;
static_assert(&A == &C, "Bug");

int main() { return 0; }

它被clang版本3.3完全接受,而g ++(SUSE Linux)4.8.1 20130909 [gcc-4_8-branch版本202388拒绝使用以下命令:

bug2.cpp:5:1: error: non-constant condition for static assertion
 static_assert(&A == &B, "Bug");
 ^
bug2.cpp:5:1: error: the value of ‘B’ is not usable in a constant expression
bug2.cpp:2:12: note: ‘B’ was not declared ‘constexpr’
 const int &B = A;
            ^

在我看来,GCC是正确的(而我当然更喜欢clang行为)。 尝试阅读标准时,我意识到我还没有足够的语言律师来决定。 谁能确认?

the value of 'B' is not usable in a constant expression是不正确的。 您没有在B上执行从左值到右值的转换,这是“值”的通常含义。 您仅使用其地址。 唯一相关的常量表达式规则禁止:

引用引用类型的变量或数据成员的id表达式,除非引用具有先前的初始化,且使用常量表达式初始化;

但是, B确实对参考常量表达式进行了初始化。

引用常量表达式是左值核心常量表达式,用于指定具有静态存储持续时间或函数的对象。

在这种情况下, B的初始值设定项是A ,它的常数要尽可能大。 AB静态引用相同的对象。

因此,这是一个GCC错误。

如果您不是语言律师,则通常不能将引用用作常量表达式,只能使用值(如果有例外,请纠正我)。 从这个意义上讲,最接近您的代码的有效值为:

constexpr int A = 42;
constexpr int B = A;

static_assert(A == B, "Bug");

但是,就我而言,Clang 3.3和GCC 4.8.1都会在您的代码上出现预期的错误。

编辑显然,我的知识仍然有点狭窄,对不起。 根据链接的不同,可能会有一些例外情况,例如,如果语句是全局的,则在main()之外接受( 实时 )代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM