Этот вопрос заставил меня подвергнуть сомнению практику, которой я следовал годами.
Для потокобезопасной инициализации функций-локальных статических объектов const я защищаю фактическую конструкцию объекта, но не инициализацию ссылки на функцию-локальную ссылку на нее. Что-то вроде этого:
namespace {
const some_type& create_const_thingy()
{
lock my_lock(some_mutex);
static const some_type the_const_thingy;
return the_const_thingy;
}
}
void use_const_thingy()
{
static const some_type& the_const_thingy = create_const_thingy();
// use the_const_thingy
}
Идея состоит в том, что блокировка занимает время, и если ссылка переписывается несколькими потоками, это не имеет значения.
Мне было бы интересно, если это
- достаточно безопасен на практике?
- безопасно в соответствии с Правилами? (Я знаю, текущий стандарт даже не знает, что такое concurrency ", но как насчет того, чтобы попирать уже инициализированную ссылку? И другие стандарты, такие как POSIX, могут что-то сказать об этом?)
Причина, по которой я хочу знать, это то, что я хочу знать, могу ли я оставить код как есть, или мне нужно вернуться и исправить это.
Для вопрошающих умов:
Многие такие локально-локальные объекты const const, которые я использовал, являются картами, которые инициализируются из массивов констант при первом использовании и используются для поиска. Например, у меня есть несколько парсеров XML, где теги имен тегов сопоставляются с значениями enum
, поэтому я мог бы позже switch
по значениям тегов enum
.
Так как у меня есть ответы на вопрос, что делать вместо этого, но у меня нет ответа на мои актуальные вопросы (см. выше пункты 1 и 2.), я начну щедрость по этому поводу. Опять же:
Мне не интересно, что я мог бы сделать вместо этого, я действительно хочу знать об этом.