Уникальные статические константы встроенной функции?

Вот пример кода:

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

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

Компонент обычно отвечает за объединение всех ссылок на использование одного и того же экземпляра.