Из "C ++ Primer, 5-е издание", стр. 407:
Все статические переменные продолжительности имеют следующие две инициализации
Особенности:
Неинициализированная статическая переменная имеет все биты, установленные на 0.
Статическая переменная может быть инициализирована только с помощью константного выражения.
В константном выражении могут использоваться литеральные константы, const и enum
константы и оператор sizeof. Следующий фрагмент кода
иллюстрирует эти моменты:
int x; // x set to 0
int y = 49; // 49 is a constant expression
int z = 2 * sizeof(int) + 1; // also a constant expression
int m = 2 * z; // invalid, z not a constant
int main() {...}
Мой вопрос - ПОЧЕМУ это стандарт? Какова (практическая) причина этого.
Какой вред был бы нанесен нам в противном случае?
Особенно мне трудно найти причину недействительности:
int m = 2 * z; // invalid, z not a constant
, поскольку z
само по себе уже известно во время компиляции.
Ответ:
Проще говоря, в соответствии со стандартом не гарантируется, что инструкции перед первым утверждением main
будут выполнены по порядку.
Однако гарантируется, что все статические хранилища будут инициализироваться нулями перед любой другой инициализацией.
Это означает, что в примере, который я привел: int m = 2 * z;
- неопределенное поведение, и m может либо вычисляться до 2*0=0
, либо может оцениваться как `2 * (2 * sizeof (int) + 1).
Вне «стандарта C ++ - ANSI ISO IEC 14882 2003» 3.6.2 (стр.44):
Объекты со статической продолжительностью хранения (3.7.1) должны быть инициализированы нулями
(8.5) перед любой другой инициализацией.
...
Реализации разрешено выполнять инициализацию
объект области имен пространства со статической продолжительностью хранения в качестве статического
инициализация, даже если такая инициализация не требуется
статически ...
...
И важный бит:
Как следствие, если инициализация объекта obj1 ссылается на
объект obj2 области имен со статической продолжительностью хранения
потенциально требует динамической инициализации и определяется позже в
та же единица перевода, не указано, является ли значение obj2
используется значение полностью инициализированного объекта obj2 (поскольку объект obj2 был
статически инициализировано) или будет значением obj2 просто
нулевой initialized.`
Дополнительная информация о проблемах такого рода:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
Редактировать: поставить в ответ. Pubby's был правильным ответом (и был принят), но я действительно пропустил часть «Как следствие ...». Кроме того, я думаю, что ссылка, которую я добавил, может быть полезной.