Прыжки через переменную инициализации плохо сформированы или это вызывает неопределенное поведение? - PullRequest
17 голосов
/ 27 января 2020

Рассмотрим этот код:

void foo()
{
    goto bar;
    int x = 0;
    bar: ;
}

G CC и Clang отклоняют его , поскольку переход к bar: обходит инициализацию переменной. MSV C не жалуется вообще (кроме использования x после bar: вызывает предупреждение).

Мы можем сделать то же самое с switch:

void foo()
{
    switch (0)
    {
        int x = 0;
        case 0: ;
    }
}

Теперь все три компилятора выдают ошибки .

Эти фрагменты плохо сформированы? Или они вызывают UB?

Раньше я думал, что оба были плохо сформированы, но я не могу найти соответствующие части стандарта. [stmt.goto] ничего не говорит об этом, и при этом [stmt.select] .

Ответы [ 2 ]

20 голосов
/ 27 января 2020

Он плохо сформирован, когда инициализация не пустая.

[stmt.dcl]

3 Это можно перенести в блок, но не так, чтобы обойти объявления с инициализацией (в том числе в условиях и инструкциях init). Программа, которая переходит с точки, где переменная с автоматическим c сроком хранения не попадает в область, до точки, где она находится в области, плохо сформирована, если переменная не имеет бессодержательной инициализации ([basi c .life]). В таком случае переменные с незаполненной инициализацией строятся в порядке их объявления.

Инициализатор делает инициализацию незаполненной. Для сравнения, этот

void foo()
{
    goto bar;
    int x; // no initializer
    bar: ;
}

будет правильно сформирован. Хотя обычные предостережения относительно использования x с неопределенным значением применимы.

3 голосов
/ 27 января 2020

С оператор goto :

Если передача управления входит в область действия любых автоматических c переменных (например, путем перехода вперед по оператору объявления), программа плохо сформирован (не может быть скомпилирован), если только все переменные, чья область ввода введена, не имеют

  1. скалярных типов, объявленных без инициализаторов
  2. типов классов с тривиальными конструкторами по умолчанию и тривиальными деструкторами, объявленными без инициализаторов
  3. cv-квалифицированные версии одного из вышеуказанных
  4. массивов одного из вышеуказанных
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...