Подтвердить что ты не робот

Каковы правила инициализации нелокальной статики?

Предположим, что у меня есть класс, единственной целью которого являются побочные эффекты, возникающие при построении его объектов (например, регистрация класса с помощью factory):

class SideEffectCauser {
public:
  SideEffectCauser() { /* code causing side-effects */ }
};

Также предположим, что я хотел бы, чтобы объект создавал такие побочные эффекты один раз для каждой из нескольких единиц перевода. Для каждой такой единицы перевода я хотел бы просто разместить объект SideEffectCauser в области пространства имен в .cpp файле, например,

SideEffectCauser dummyGlobal;

но 3.6.2/3 стандарта С++ 03 предполагает, что этот объект не нужно создавать вообще, если не используется объект или функция в файле .cpp, а такие статьи, как this и онлайн-обсуждения, такие как это, предполагают, что такие объекты иногда не инициализируются.

С другой стороны, Есть ли способ создать объекты из строки, содержащей их имя класса? имеет решение, которое, как утверждается, работает, и я отмечаю, что он основан на использовании объекта типа типа SideEffectCauser как статического члена данных, а не как глобального, например,

class Holder {
  static SideEffectHolder dummyInClass;
};

SideEffectHolder Holder::dummyInClass;

Оба dummyGlobal и dummyInClass являются нелокальной статикой, но более близкий взгляд на 3.6.2/3 стандарта С++ 03 показывает, что этот отрывок применяется только к объектам в области пространства имен. Я не могу найти ничего в стандарте С++ 03, который говорит, что динамическая инициализация нелокальной статики в области классов, хотя 9.4.2/7 предполагает, что к ним применяются те же правила, что и для нелокальной статики в пространстве имен сфера.

Вопрос 1: В С++ 03 есть ли основания полагать, что dummyInClass скорее всего будет инициализироваться, чем dummyGlobal? Или оба могут быть неинициализированы, если не используются никакие функции или объекты в одной и той же системе переводов?

Вопрос 2: Что-нибудь изменилось в С++ 11? Формулировка в разделах 3.6.2 и 9.4.2 не совпадает с версиями С++ 03, но из того, что я могу сказать, не существует никакой поведенческой разницы, указанной для описанных выше сценариев.

Вопрос 3: Существует ли надежный способ использования объектов класса типа SideEffectHolder вне тела функции для принудительного выполнения побочных эффектов?

4b9b3361

Ответ 1

Я думаю, что единственным надежным решением является его разработка для конкретных компиляторов и исполняемых файлов. Стандарт не включает инициализацию глобалов в общей библиотеке, которая, по моему мнению, является самым сложным случаем, так как она во многом зависит от загрузчика и, следовательно, зависит от ОС.

Q1: Нет Q2: Не в каком-либо практическом смысле Q3: Не стандартным способом.

Ответ 2

Я использую что-то подобное с g++/С++ 11 под Linux и получаю свои фабрики, как и ожидалось. Я не уверен, почему вы не получили бы вызванные функции. Если то, что вы описали, должно быть реализовано, это будет означать, что каждая отдельная функция в этом устройстве должна вызывать функцию инициализации. Я не слишком уверен, как это можно сделать. Мои заводы также находятся внутри пространств имен, хотя они называются пространствами имен. Но я не понимаю, почему это не будет вызвано.

namespace snap {
namespace plugin_name {
class plugin_name_factory {
public:
  plugin_name_factory() { plugin_register(this, name); }
...
} g_plugin_name_factory;
}
}

Обратите внимание, что ключевое слово static больше не должно использоваться в С++. Часто медленнее иметь статическое определение, чем глобальное.