g++可以将const视为constexpr在static_assert中使用。

3

使用g++ 4.8.2编译以下代码,并使用-std=c++11标志,可以无错误编译:

    constexpr double C = 299792.458;
    const double local_max = 3.5;
    static_assert(local_max < C, "can't go that fast");

编译以下代码时出现错误:
    constexpr double C = 299792.458;
    double x = 3.5;
    const double local_max = x;
    static_assert(local_max < C, "can't go that fast");

错误信息:

a.cc: 在函数‘int main()’中:

a.cc:6:2: 错误:静态断言的非常量条件
static_assert(local_max < C, "can't go that fast");

a.cc:6:2: 错误:‘local_max’的值在常量表达式中不可用

a.cc:5:15: 注意:‘local_max’未声明为‘constexpr’ const double local_max = x;

我的问题是为什么第一个情况没有出错。
这是否取决于是否使用constexpr初始化const变量?

2
x 在运行时获得其值,而 static_assert 是编译时断言。你不能基于 x 进行 static_assert。 - Melkon
2个回答

3

您说得完全正确,在

const double local_max = 3.5;

local_max仍然不应该是编译时常量。这是一个编译器错误,在GCC 5.1中已经修复。您可以在gcc.godbolt.org上验证,您将看到GCC的错误消息,包括:

错误:'local_max'的值在常量表达式中不可用

注意:'local_max'未声明为'constexpr'


1
为什么它不能是编译时常量?那么为什么 const int i = 0; int x[i] 可以编译通过呢? - David G
1
@0x499602D2 整数类型的规则是特殊的。OP所猜测的(如果使用常量表达式初始化,则隐式地应用constexpr)确实适用于整数类型,以便让大多数有效的C++03代码也成为有效的C++11代码。 - user743382

-1

第一个版本可以工作,因为local_max不会在内存中。每当使用local_max时,它将被替换为其值,该值在编译时已知。因此,您可以基于它调用static_assert。

然而,在第二个版本中,local_max根据x获取其值,而x在运行时获取其值。

您无法基于在运行时获取其值的变量进行static_assert,因为static_assert是编译时断言。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接