Оператор объявления вводит в блок один или несколько новых идентификаторов; это имеет форму
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 метке считается скачком в этом отношении.
Реализация не должна создавать взаимоблокировки при выполнении инициализатора. Тупики по-прежнему могут быть вызваны логикой программы; реализации нужно только избегать взаимоблокировок из-за собственных операций синхронизации.