static
переменные полностью инициализируются перед выполнением любой функции в том же блоке перевода (файл cpp более или менее). Они не гарантированно инициализируются до того, как вызывается main
, если main
находится в другой единицы перевода. inline
дублируются, где каждая единица перевода имеет свою собственную копию. Это означает, что встроенные функции в разных единицах перевода, чем переменная static
, могут попытаться прочитать/записать эту переменную до ее правильной инициализации, что приведет к неопределенному поведению. (Правила очень сложны, но это то, что я помню)
§ 3.6.2/4 Реализовано определение того, выполняется ли динамическая инициализация нелокальной переменной со статической продолжительностью хранения до первого оператора основного. Если инициализация отложена до некоторого момента времени после первого утверждения main, она должна произойти до первого использования odr (3.2) любой функции или переменной, определенной в той же самой единицы перевода, что и инициализированная переменная.
и
§ 3.2/3 Функция инлайн должна быть определена в каждой единице перевода, в котором он ODR использовать.
встроенные функции на самом деле не являются более опасными, чем не встроенные функции, насколько я знаю. Любая функция, обращающаяся к статике в другом ТУ, является рискованной, и поскольку inline
просто выполняет функции в каждый TU, большинство из них небезопасны. Одним из способов является использование "construct on first use idiom".
Неявные специализации шаблона являются сложными, но для полноты:
§ 14.7.1/3 [temp.inst] инициализация (и любые связанные с ними побочные эффекты) статического члена данных не происходит, если элемент статических данных сам используется таким образом, который требует определения статического члена данных.
Таким образом, статические члены классов шаблонов всегда инициализируются перед использованием.
Все вышеперечисленное подпадает под действие the static initialization order fiasco), которое решает вышеупомянутая «конструкция при первом использовании идома».
Я никогда не думал об этом раньше, но да, это проблема, не так ли? –
Какой часто задаваемый вопрос? – Slava
Обычно «C++ FAQ» относится к [this] (http: // http: //www.parashift.com), но [16.4 на этом сайте не имеет ничего общего с встроенным или статическим] (http: // www. parashift.com/c++-faq/new-vs-malloc.html), поэтому я не уверен в этом случае. Я не могу найти эту проблему, упомянутую на сайте, на котором я вообще связан. –