9 Statements [stmt.stmt]

9.7 Declaration statement [stmt.dcl]

Оператор объявления вводит в блок один или несколько новых идентификаторов; это имеет форму

declaration-statement:
	block-declaration

Если идентификатор, введенный объявлением, был ранее объявлен во внешнем блоке, внешнее объявление скрывается до конца блока, после чего оно возобновляет свою силу.

Переменные с automatic storage duration инициализируются каждый раз при их declaration-statementвыполнении. Переменные с автоматической продолжительностью хранения, объявленные в блоке, уничтожаются при выходе из блока ([stmt.jump]).

Можно передать в блок, но не в обход объявлений с инициализацией. Программа, которая перескакивает91 из точки, где переменная с автоматической продолжительностью хранения не находится в области видимости, к точке, где она находится в области видимости, плохо сформирована, если только переменная не имеет скалярный тип, тип класса с тривиальным конструктором по умолчанию и тривиальный деструктор, a cv-квалифицированная версия одного из этих типов или массив одного из предыдущих типов, объявленный без расширения initializer. [Example:

void f() {
  // ...
  goto lx;          // ill-formed: jump into scope of a
  // ...
ly:
  X a = 1;
  // ...
lx:
  goto ly;          // OK, jump implies destructor call for a followed by
                    // construction again immediately following label ly
}

end example]

Динамическая инициализация переменной области блока с помощью static storage duration или thread storage duration выполняется при первом прохождении управления через ее объявление; такая переменная считается инициализированной по завершении ее инициализации. Если инициализация завершается выдачей исключения, инициализация не завершена, поэтому она будет повторена, когда в следующий раз элемент управления войдет в объявление. Если элемент управления входит в объявление одновременно во время инициализации переменной, параллельное выполнение должно дождаться завершения инициализации.92 Если элемент управления повторно входит в объявление рекурсивно во время инициализации переменной, поведение не определено. [Example:

int foo(int i) {
  static int s = foo(2*i);      // recursive call - undefined
  return i+1;
}

end example]

Деструктор для объекта блочной области со статической продолжительностью хранения или продолжительностью хранения потока будет выполняться тогда и только тогда, когда он был создан. [ Note: [basic.start.term] описывает порядок, в котором уничтожаются объекты блочной области со статической продолжительностью хранения и продолжительностью хранения потоков. ]end note

Переход от условия switch оператора к case метке считается скачком в этом отношении.

Реализация не должна создавать взаимоблокировки при выполнении инициализатора. Тупики по-прежнему могут быть вызваны логикой программы; реализации нужно только избегать взаимоблокировок из-за собственных операций синхронизации.