Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Справочник по С++.doc
Скачиваний:
49
Добавлен:
02.05.2014
Размер:
995.33 Кб
Скачать

R.6.7 Оператор описания

Оператор описания заводит в блоке новый идентификатор и имеет вид: оператор-описания: описание Если идентификатор, введенный с помощью описания, уже был ранее описан во внешнем блоке, внешнее описание становится скрытым до конца блока, после чего оно опять вступает в силу. Все инициализации автоматических (auto) и регистровых (register) переменных производятся каждый раз, когда выполняется оператор-описание. Уничтожение локальных переменных, описанных в блоке, происходит при выходе из блока ($$R.6.6). Уничтожение автоматических переменных, определенных в цикле, происходит на каждом шаге цикла. Например, переменная Index j создается и уничтожается каждый раз в течение цикла по i: for (int i = 0; i<100; i++) for (Index j = 0; j<100; j++) { // ... } Выход из цикла или из блока или переход, минуя инициализацию автоматических переменных, приводит к уничтожению автоматических переменных, описанных в точке, откуда происходит переход, но не в точке, куда происходит переход. Переход в блок возможен при условии, что он не приводит к пропуску инициализации. Считается незаконным переход, обходящий описание с явной или неявной инициализацией, кроме случаев, когда оно находится во внутреннем блоке, который пропускается (т.е. в него никогда не попадает управление) или переход происходит из той точки, где уже была инициализация переменной. Например, void f() { // ... goto lx; //ошибка: переход, минуя инициализацию // ... ly: X a = 1; // ... lx: goto ly; // нормально, за переходом будет вызов // деструктора для `a' } Автоматическая переменная, которая была создана при некотором условии, уничтожается при выполнении этого условия, и не может быть доступна вне проверки этого условия. Например, if (i) for (int j = 0; j<100; j++) { // ... } if (j!=100) // ошибка: обращение вне условия // ... ; Инициализация локального объекта с классом памяти static ($$R.7.1.1) производится прежде, чем управление пройдет через область его описания. Если статическая переменная инициализируется выражением, которое не является выражением-константой, то перед первым входом в блок происходит стандартная инициализация нулем, приведенным к нужному типу ($$R.8.4). Деструктор для локального статического объекта будет вызываться в том и только в том случае, если переменная была создана с помощью конструктора. Деструктор должен вызываться сразу перед вызовом или как составная часть вызова функций, заданных в atexit() ($$R.3.4).

R.6.8 Разрешение неоднозначности

Существует неоднозначность в грамматике языка, касающаяся оператора-выражения и описания, а именно, оператор-выражение, содержащий как самое левое подвыражение явное преобразование типа, заданное в функциональном стиле ($$R.5.2.3), может быть не отличим от описания, в котором первый описатель начинается со (. В таких случаях оператор считается описанием. Для разрешения неоднозначности следует исследовать весь оператор, чтобы определить является он оператором-выражением или описанием. Так устраняется неоднозначность во многих случаях. Например, пусть T - имя-простого-типа ($$R.7.1.6), тогда имеем T(a)->m = 7; // оператор-выражение T(a)++; // оператор-выражение T(a,5)<<c; // оператор-выражение T(*e)(int); // описание T(f)[]; // описание T(g) = {1, 2 }; // описание T(*d)(double(3)); // описание Остальные случаи представляют описания. Например, T(a); // описание T(*b)(); // описание T(c)=7; // описание T(d),e,f=3; // описание T(g)(h,2); // описание Неоднозначность здесь чисто синтаксическая, т.е. на ее разрешение не влияет тот факт, является ли имя именем-типа или нет. Есть другой вид коллизии между оператором-выражением и описанием, который разрешается требованием, чтобы описание функции в блоке ($$R.6.3) сопровождалось именем-типа, например: void g() { int f(); // описание int a; // описание f(); // оператор-выражение a; // оператор-выражение }