这是合理的跳转到标签编译错误与constexpr变量的初始化

时间:2018-06-11 09:50:08

标签: c++ c++11 c++14 c++17

我发现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;
}

2 个答案:

答案 0 :(得分:2)

  

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

Yes, it apparently still is

您可以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允许它并没有多大意义(要么你可以在跳转之外或在局部范围内初始化它。)