Я пытаюсь узнать об инициализации статических объектов. Статическая инициализация кажется довольно прямой, если вы понимаете постоянные выражения и constexpr
. Динамическая инициализация кажется несколько более сложной.
[basic.start.init]/4
Реализация - определяет, выполняется ли динамическая инициализация нелокальной переменной со статической продолжительностью хранения до первой основной записи. Если инициализация отложена до некоторого момента времени после первого утверждения main, она должна произойти до первого использования odr (3.2) любой функции или переменной, определенной в той же самой единицы перевода, что и инициализированная переменная.
сноска 34
Нелокальная переменная со статической продолжительностью хранения, имеющей инициализацию с побочными эффектами, должна быть инициализирована, даже если она не используется в качестве odr (3.2, 3.7.1).
[basic.start.init]/5
Реализовано определение того, выполняется ли динамическая инициализация нелокальной переменной со статической или длительностью хранения потоков до первого утверждения начальной функции потока. Если инициализация отложена до некоторого момента времени после первого утверждения начальной функции потока, она должна произойти до первого использования odr (3.2) любой переменной с продолжительностью хранения потоков, определенной в той же самой единицы перевода, что и переменная для инициализации.
Я предполагаю, что "начальная функция потока" относится к основным, а не только к потокам, запущенным с помощью std:: thread.
h1.h
#ifndef H1_H_
#define H1_H_
extern int count;
#endif
tu1.cpp
#include "h1.h"
struct S
{
S()
{
++count;
}
};
S s;
tu2.cpp
#include "h1.h"
int main(int argc, char *argv[])
{
return count;
}
tu3.cpp
#include "h1.h"
int count;
Итак, если компилятор отменил динамическую инициализацию, кажется, что в сноске 34 указано, что s
необходимо инициализировать в какой-то момент. Поскольку в блоке трансляции нет других переменных с динамической инициализацией, нет никакой другой переменной для использования odr для принудительной инициализации переменных в tu1. В какой момент s
гарантированно был инициализирован?
Гарантировано ли возвращение 1? Кроме того, есть ли способ изменить эту программу, чтобы больше не было гарантировано вернуть 1? В качестве альтернативы, если это не гарантировано, есть ли способ изменить эту программу таким образом, чтобы она гарантировалась?
Я сломал код так, чтобы определение s
находилось в другой единицы перевода от main
. Это позволяет избежать вопроса о том, используется ли main
odr. Учитывая, что s
является единственным объектом в блоке перевода, гарантируется, что main
вернет 1?