这是通过初始化 constexpr 变量来标记编译错误的合理跳转



我发现在 C++11 中跳过constexpr变量时交叉初始化仍然会计算编译时错误(至少在我的编译环境中(

请考虑以下代码:

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?

=== 更新 ===

另一个不使用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;
}

任何人都可以告诉我,在更高的标准中,它仍然是错误吗,例如C++14,C++17?

是的,它显然仍然是。

您可以引入一个范围来解决问题,这也消除了有关初始化、生存期等的任何担忧。

您不能用goto(或switch结构内的跳转(交叉任何初始化,无论它是constconstexpr还是两者都不是。 使用 GCC,您可以使用-fpermissive编译代码,但如果您真的认为需要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;
}

我不知道标准的相应部分,但我想这是不允许的原因是,对于非constexpr,在访问在goto和标签之间初始化的变量时,您会得到不清楚的行为。并且只允许它用于constexpr并没有真正的意义(您可以在跳转之外或本地范围内初始化它(。

相关内容

最新更新