Решает ли С++ 17 «статический встроенный» фиаско статического порядка инициализации?

avatar
Peter Fletcher
8 августа 2021 в 22:39
168
0
0

Я иногда сталкивался с "фиаско статического порядка инициализации C++", когда некоторый сложный глобальный объект (например, хеш-таблица) используется другим классом до того, как он был создан, что иногда приводило к сбоям во время инициализации перед main()

Как известно, этого фиаско можно избежать, внедрив части объекта, требующие инициализации, в виде статики в функцию-член, потому что статика в функции всегда инициализируется при первом входе в функцию, например :

struct GlobalHashTable
{
   std::map <std::string, int>& stringmap()
   {
       static std::map <std::string, int> stringmap;
       
       return stringmap;
   }

... (remainder safely uses stringmap() to get at properly-initialized map object)
};

Похоже, что "статические встроенные" объекты имеют сходную семантику с этими объектами, встроенными в функцию. Можно ли их безопасно использовать внутри класса, избегая фиаско?

Например,

struct GlobalHashTable
{
   static inline std::map <std::string, int> stringmap;

... (remainder safely uses stringmap to get at properly-initialized map object)
};
Источник
Fureeish
8 августа 2021 в 22:42
2

"Похоже, что "статические встроенные" объекты имеют сходную семантику с этими объектами-встроенными-в-функцию." - почему вы так говорите? Что это за подобная семантика?

Peter Fletcher
8 августа 2021 в 22:48
0

На встроенный объект могут ссылаться несколько объектных файлов, но при этом гарантируется, что он будет инициализирован ровно один раз, и я полагаю, что для этого существует своего рода защита вокруг его использования.

Fureeish
8 августа 2021 в 22:58
1

Поле, отличное от inline, static, также гарантированно инициализируется ровно один раз, и на него могут ссылаться несколько объектных файлов. Добавление inline не добавляет дополнительных требований к заказу.

Peter Fletcher
8 августа 2021 в 23:19
0

Не встроенный статический объект должен быть определен ровно в одном объектном файле, где он инициализируется. Требования к заказу кажутся очень разными.

Fureeish
9 августа 2021 в 00:15
1

Какие точные требования к заказу? Пожалуйста, обратитесь к определенному разделу стандарта или справочнику.

Peter Fletcher
9 августа 2021 в 02:11
0

Я не понимаю: я не говорил, что требования к заказу были точными. Я сказал, что статический объект инициализируется ровно в одном объектном файле, что очевидно.

Fureeish
9 августа 2021 в 02:21
0

Инициализация только в одном объектном файле никак не связана с порядком других возможных инициализаций. Вы продолжаете говорить «кажется», но я не вижу где вы видите что-либо, что поддерживает ваше утверждение.

Peter Fletcher
9 августа 2021 в 03:05
0

См. здесь обсуждение защиты встроенных переменных. Эти охранники не существуют со статическими переменными. coderhelper.com/questions/56798437/…

Fureeish
9 августа 2021 в 14:08
0

Давайте продолжим эту дискуссию в чате.

Ответы (0)