Уникальные статические константы встроенной функции?
Вот пример кода:
enum Foo // or enum class whatever
{ BAR
, STUFF
};
inline const char* to_string( const Foo& foo )
{
static const char* const NAMES[] =
{ "BAR"
, "STUFF"
};
// let assume I have some boundary checks here, it not the point
return NAMES[foo];
};
Эта функция встроена, находится в заголовке, используемом в нескольких единицах компиляции.
Цель состоит в том, чтобы заставить компилятор ничего не делать, если эта функция не используется.
Вопросы:
- Предоставляет ли стандарт С++, что NAMES будет существовать только в одном объектном файле или оставить его компилятору, чтобы решить или он гарантирует, что каждый объектный файл будет иметь его копию?
- Если будет несколько копий, будет ли это проблемой связывания (я предполагаю, что не могу проверить достаточное количество компиляторов, чтобы проверить это).
- Будет ли gcc, msvc и clang оптимизировать этот случай, если в конечном бинарнике будет только один экземпляр NAMES?
Ответы
Ответ 1
Да, стандарт гарантирует, что будет только один объект. Из С++ 03 §7.1.2/4:
[...] A static
Локальная переменная в функции extern inline
всегда относится к одному и тому же объекту. Строковый литерал в Внешняя встроенная функция - это один и тот же объект в разных единицах перевода.
(Обратите внимание, что функция extern inline
представляет собой функцию inline
с внешней связью, т.е. функцию inline
, не помеченную как static
.)
Точно, какой файл объекта, в котором он появляется, будет зависеть от компилятора, но я подозреваю, что каждый объектный файл, который его использует, получит копию, и компоновщик будет произвольно выбирать один из символов и отбрасывать остальные.
Ответ 2
Стандарт гарантирует, что будет использоваться только одна копия. Это не гарантирует, что в коде не будут использоваться неиспользуемые копии.
Компонент обычно отвечает за объединение всех ссылок на использование одного и того же экземпляра.