global static != local static
От: mbait  
Дата: 28.04.18 10:29
Оценка: 3 (1) -2
TLDR; static (const) переменные в global scope работяют как в Си, в local scope создаётся туча кода с мьтексами, блокировками и бросанием исключений.

Снова и снова я возвращаюсь к С++ с мыслями "ну, может не такой он и стрёмный? в конце-концов RAII, можно красиво писать" и каждый раз какое-то говно находится. В этот раз — https://manishearth.github.io/blog/2015/06/26/adventures-in-systems-programming-c-plus-plus-local-statics/. А что там было насчёт "не плати за то, что не используешь?", а что насчёт move semantics и precondition? Почему тут нельзя было так же сделать: объявил локально статичную переменную — будь добр не вызывать эту функцию абы как?
Re: global static != local static
От: Constructor  
Дата: 28.04.18 10:51
Оценка: 2 (1)
Здравствуйте, mbait, Вы писали:

M>Почему тут нельзя было так же сделать: объявил локально статичную переменную — будь добр не вызывать эту функцию абы как?


Так и было до C++11, в котором появились т.н. magic statics. Если не хотите платить за эту магию, используйте C++03 и/или обычные глобальные статические переменные в C++11+.
Re: global static != local static
От: Alexander G Украина  
Дата: 28.04.18 11:00
Оценка: 2 (1)
Здравствуйте, mbait, Вы писали:

M>Почему тут нельзя было так же сделать: объявил локально статичную переменную — будь добр не вызывать эту функцию абы как?


Хорошая реализация имеет минимальный оверхед.

Если так уж нужна не-потокобезопасная инциализация, можно это дело провернуть ну хотя бы так
{
   static std::optional<X> x; // не будет безопасной ленивой инициализации, т.к. конструктор constexpr
   if (!x) x.emplace(...); // небезопасная ленивая инициализация
}


Но в целом, она скорее не нужна, чем нужна.
Многопоточность может потребоваться там, где её совсем не ждали.
Русский военный корабль идёт ко дну!
Re: global static != local static
От: Vamp Россия  
Дата: 28.04.18 11:21
Оценка: +3
Если не уметь пользоваться языком, то грабли будут все время больно бить по лбу.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: global static != local static
От: mbait  
Дата: 28.04.18 11:39
Оценка: :)
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, mbait, Вы писали:


M>>Почему тут нельзя было так же сделать: объявил локально статичную переменную — будь добр не вызывать эту функцию абы как?


AG>Хорошая реализация имеет минимальный оверхед.


AG>Если так уж нужна не-потокобезопасная инциализация, можно это дело провернуть ну хотя бы так

AG>
AG>{
AG>   static std::optional<X> x; // не будет безопасной ленивой инициализации, т.к. конструктор constexpr
AG>   if (!x) x.emplace(...); // небезопасная ленивая инициализация
AG>}
AG>


AG>Но в целом, она скорее не нужна, чем нужна.

AG>Многопоточность может потребоваться там, где её совсем не ждали.

У меня больше был вопрос: почему нельзя выполнять инициализацию до вызова main? Тогда и обвязка бы не понадобилась. Или хотя бы сделать так, если одновременно и static, и const?
Re[3]: global static != local static
От: Alexander G Украина  
Дата: 28.04.18 12:04
Оценка: 2 (1)
Здравствуйте, mbait, Вы писали:


M>У меня больше был вопрос: почему нельзя выполнять инициализацию до вызова main? Тогда и обвязка бы не понадобилась.


А, ну такая семантика уже не в С++11 появилось, а в старом С++, когда ещё не требовалась потокобезопасность.
Она востребована, например, многие слышали про "синглтон Мейерса".

С не-ленивой инициализацией до main можно столкнуться со следующими проблемами:
1. Порядок инициализации, зависимости между этими статическими объектами
2. О ужас, у нас может быть многопоточность уже до main
3. Нужны параметры, которые приходят только при вызове функции

M>Или хотя бы сделать так, если одновременно и static, и const?


Если там совсем constexpr, то так оно и будет. А const толком ничего не гарантирует.
Русский военный корабль идёт ко дну!
Re[2]: global static != local static
От: andrey.desman  
Дата: 28.04.18 12:13
Оценка:
Здравствуйте, Constructor, Вы писали:

C>Так и было до C++11, в котором появились т.н. magic statics. Если не хотите платить за эту магию, используйте C++03 и/или обычные глобальные статические переменные в C++11+.


GCC и в C++03 инициализирует потокобезопасно. Насчет VC++ не уверен, но вроде тоже.
Re: global static != local static
От: andrey.desman  
Дата: 28.04.18 12:16
Оценка:
Здравствуйте, mbait, Вы писали:

M>TLDR; static (const) переменные в global scope работяют как в Си, в local scope создаётся туча кода с мьтексами, блокировками и бросанием исключений.


Локальные статики нужны, если хочется не конструировать объект, если не используешь (то самое "не плати"), и/или параметры для конструирования приходят в функцию аргументами и/или хочется иметь контроль за очередностью инициализации.
Если тебе все это не нужно, не используй локальные статики, в чем проблема-то?
Re[3]: global static != local static
От: Alexander G Украина  
Дата: 28.04.18 13:55
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Насчет VC++ не уверен, но вроде тоже.


У VC++ нет опции выбора между С++03 и С++11, magic static появился с VC14 (2015), и есть опция для отключения magic static.
Русский военный корабль идёт ко дну!
Re[2]: global static != local static
От: Vamp Россия  
Дата: 28.04.18 17:40
Оценка:
Если не хотите платить за эту магию, используйте C++03 и/или обычные глобальные статические переменные в C++11+.

Для начала хорошо бы разобраться, как именно вы платите. Во всех известных мне современных архитектурах после первоначальной инициализации плата — это один бранч, который предсказывается правильно с третьего раза. Так что разговор о платетя считаю неуместным.
Да здравствует мыло душистое и веревка пушистая.
Re: global static != local static
От: σ  
Дата: 29.04.18 01:21
Оценка: +1
M>static (const) переменные в global scope работяют как в Си, в local scope создаётся туча кода с мьтексами, блокировками и бросанием исключений.
Re[2]: global static != local static
От: mbait  
Дата: 29.04.18 07:38
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Локальные статики нужны, если хочется не конструировать объект, если не используешь (то самое "не плати"), и/или параметры для конструирования приходят в функцию аргументами и/или хочется иметь контроль за очередностью инициализации.

AD>Если тебе все это не нужно, не используй локальные статики, в чем проблема-то?

В Си локальные статики это один из приёмов сохранения области имён чистой с одновременной оптимизацией кода. Правда, стоит отметить, что всё, что можно объявить в Си static const, можно объявить в C++ static constexpr, и тогда вспомогательный код не будет сгенерирован.
Re[3]: global static != local static
От: andrey.desman  
Дата: 29.04.18 09:24
Оценка:
Здравствуйте, mbait, Вы писали:

M>В Си локальные статики это один из приёмов сохранения области имён чистой с одновременной оптимизацией кода. Правда, стоит отметить, что всё, что можно объявить в Си static const, можно объявить в C++ static constexpr, и тогда вспомогательный код не будет сгенерирован.



Все, что в Си можно объявить static const, в С++ можно так же объявить static const и тоже без вспомогательного кода, потому что pod.
Re[3]: global static != local static
От: Pzz Россия https://github.com/alexpevzner
Дата: 29.04.18 11:54
Оценка:
Здравствуйте, mbait, Вы писали:

M>У меня больше был вопрос: почему нельзя выполнять инициализацию до вызова main? Тогда и обвязка бы не понадобилась. Или хотя бы сделать так, если одновременно и static, и const?


Сильно легче бы не стало, потому что конструкторы этих переменных могут обращаться к другим подобным переменным, порождать потоки и всякое такое.

Отлаживаться было бы очень эротично: программа еще до main'а не дошла, а в ней уже непонятно, что происходит
Re[4]: global static != local static
От: Mr.Delphist  
Дата: 08.05.18 13:56
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Отлаживаться было бы очень эротично: программа еще до main'а не дошла, а в ней уже непонятно, что происходит


Ну, большинство startup crash именно так и происходят: порядок инициализации вдруг меняется на неожидаемый, и... Особенно в релизных сборках.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.