Константа created нигде не используется. Конструкция с ней сделана только для того, чтобы не запариваться с once_flag/call_once для вызова create_directories(). Код получается лаконичнее и чище.
Однако, пришла мысль — ну как компилятор увидит, что константа не используется, и выкинет вызов create_directories()?
Вопрос — что о такой ситуации говорит Стандарт?
Я нашел немного про gcc: "Static variables that are not used (or only written to), whose address is not taken or does not escape, are removed. Static functions that are called only once are inlined, those that are never called are never generated (unless you take pointers to them)."
Но хотелось бы узнать, что говорит на этот счет Стандарт.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Вот я бы представил, что вызывается std::filesystem::create_directories(PathToLog) без всяких присваиваний переменным.
Компилятор как будет судить об отсутствии side effects?
Никак, тем более, что тут они очевидно (для программиста, а не компилятора) есть.
Re: Выкинет ли оптимизатор код инициализации неиспользуемой пере
B>Константа created нигде не используется. Конструкция с ней сделана только для того, чтобы не запариваться с once_flag/call_once для вызова create_directories(). Код получается лаконичнее и чище.
А как код компилируется без атрибута [[maybe_unused]] и без предупреждений? Надеюсь, это тут на форуме не написан атрибут, а не в компиляторе предупреждения выключены.
B>Вопрос — что о такой ситуации говорит Стандарт?
Стандарт говорит, что компилятор вправе делать что угодно, если это не меняет наблюдаемое поведение программы.
B>Я нашел немного про gcc: B>"Static variables that are not used (or only written to), whose address is not taken or does not escape, are removed.
Если gcc выкинет переменную created, оставив защищающий её guard и первый вызов create_directories, то наблюдаемое поведение программы не изменится. Так что gcc так может делать и вправду делает. Такие действия gcc удовлетворяют требованиям языка C++.
Re[2]: Выкинет ли оптимизатор код инициализации неиспользуемой пере
Здравствуйте, reversecode, Вы писали:
R>введите в гугле R>call_once vs static R>и почитайте R>там много флуда на разных площадках, еще и видосики в ютубе
Вот именно, что флуда ((
Я почитал бегло, но вопрос выкинет или нет там не поднимается...
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[3]: Выкинет ли оптимизатор код инициализации неиспользуемой пере
правильно
там поднимается вопрос что лучше
и зачем вообще изобрели call_once это есть чудесные статик переменные
тонко вам намекаю что не всяко статик лучше в целом чем обсуждение что там выкинет компиль
Re[2]: Выкинет ли оптимизатор код инициализации неиспользуемой пере
Здравствуйте, watchmaker, Вы писали:
W>А как код компилируется без атрибута [[maybe_unused]] и без предупреждений? Надеюсь, это тут на форуме не написан атрибут, а не в компиляторе предупреждения выключены.
Прекрасно компилируется безо всяких предупреждений. Атрибута нет. Visual Studio 2019 Version 16.11.26, уровень предупреждений /W4.
B>>Вопрос — что о такой ситуации говорит Стандарт?
W>Стандарт говорит, что компилятор вправе делать что угодно, если это не меняет наблюдаемое поведение программы.
Спасибо. То есть если у переменной нетривиальная инициализация, ее выкинуть не могут?
B>>Я нашел немного про gcc: B>>"Static variables that are not used (or only written to), whose address is not taken or does not escape, are removed.
W>Если gcc выкинет переменную created, оставив защищающий её guard и первый вызов create_directories, то наблюдаемое поведение программы не изменится. Так что gcc так может делать и вправду делает. Такие действия gcc удовлетворяют требованиям языка C++.
Такое поведение меня вполне устроит. Только речь не о gcc ))
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[4]: Выкинет ли оптимизатор код инициализации неиспользуемой пере
Переменную компилятору разрешено выкинуть (опять же, если она не используется потом).
Код инициализации компилятору разрешено выкинуть только если он заменит его другим кодом с таким же наблюдаемым поведением. То есть в данном случае это означает, что при каждом входе в функцию должна будет вызываться create_directories до тех пор, пока этот вызов не завершится без выбрасывания исключения.
Просто потому что у вызова create_directories есть как собственные наблюдаемые эффекты, так и поведение другого кода может всё равно видеть результат этого вызова (например, по наличию исключения filesystem_error, выброшенного из DoLogging) и также менять своё поведение.