Это резонируемый переход к ошибке компиляции метки с инициализацией переменных constexpr - PullRequest
0 голосов
/ 11 июня 2018

Я обнаружил, что пересечение инициализации 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 голосов
/ 11 июня 2018

Вы не можете пересечь любую инициализацию с goto (или прыжком внутри конструкции switch), независимо от того, является ли она const, constexpr или ни тем, ни другим.С помощью 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 на самом деле не имеет смысла (либо вы можете инициализировать его вне прыжка, либо внутри локальной области видимости).

0 голосов
/ 11 июня 2018

Любой может сказать мне, это все еще ошибка в более высоком стандарте, например, C ++ 14, C ++ 17?

Да, это очевидно.

Вы можете ввести область действия , чтобы устранить проблему, что также устраняет любые проблемы, связанные с инициализацией, временем жизни и т. д.

...