我发现constexpr
变量的交叉初始化在跳过它时仍会计算编译时错误,在C ++ 11中(至少在我的编译环境中)
请考虑以下代码:
t foo()
{
return 1;
}
int main()
{
int T = foo();
if (T == 0)
goto JumpLabel;
constexpr int lowBound = 3;
constexpr int upBound = 10;
if (T >= lowBound && T <= upBound)
return 1;
JumpLabel:
return 0;;
}
goto
语句在C ++ 11中触发编译时错误。这个错误合理吗?它只是constexpr
个变量的交叉,它没有初始化!我只有C ++ 11编译器。任何人都可以告诉我,它是否仍然是更高标准的错误,例如,C ++ 14,C ++ 17?
=== UPDATE ===
另一个不使用goto
同一问题的程序:
int bar()
{
return 3;
}
int foo()
{
return 1;
}
int main()
{
int T = foo();
int U = bar();
switch (T) {
case 0:
constexpr int lowBound = 3;
constexpr int upBound = 10;
if (U >= lowBound && U <= upBound)
return 1;
default:
T = -1;
}
return T;
}
答案 0 :(得分:2)
任何人都可以告诉我,它是否仍然是更高标准的错误,例如,C ++ 14,C ++ 17?
您可以introduce a scope来解决您的问题,这也消除了有关初始化,生命周期等问题。
答案 1 :(得分:2)
您无法与goto
(或switch
构建内的跳转)进行任何初始化,无论是const
,{ {1}}或两者都没有。
使用GCC,您可以compile your code using -fpermissive
,但如果确实认为您需要constexpr
,请将变量初始化放在本地范围内(也可以在goto
标签之后):
switch
或者在跳转之前(或在 if (T == 0)
goto JumpLabel;
{
constexpr int lowBound = 3;
constexpr int upBound = 10;
if (T >= lowBound && T <= upBound)
return 1;
}
JumpLabel:
return 0;
之外)
switch
我不知道标准的相应部分,但我想这是不允许的原因,因为对于非constexpr int lowBound = 3;
constexpr int upBound = 10;
switch (T) {
case 0:
if (U >= lowBound && U <= upBound)
return 1;
default:
T = -1;
}
,当访问在{之间初始化的变量时,你会得到不明确的行为{1}}和标签。仅仅为constexpr
允许它并没有多大意义(要么你可以在跳转之外或在局部范围内初始化它。)