10

这是一个示例代码:

enum Foo // or enum class whatever
{   BAR
,   STUFF
};

inline const char* to_string( const Foo& foo )
{
    static const char* const NAMES[] = 
    {    "BAR"
    ,    "STUFF"
    };
    // let's assume I have some boundary checks here, it's not the point
    return NAMES[foo];
};

这个函数是内联的,在几个编译单元中使用的一个头文件中。这里的目标是如果不使用这个函数,编译器什么也不做。

问题:

  1. C++ 标准是否保证 NAMES 只存在于一个目标文件中,还是由编译器决定,还是保证每个目标文件都有它的副本?
  2. 如果会有多个副本,是否会出现链接问题(我假设我无法测试足够的编译器来检查)。
  3. gcc、msvc 和 clang 是否都会通过使最终的二进制文件只有一个 NAMES 实例来优化这种情况?
4

2 回答 2

7

是的,标准保证只有一个对象。从 C++03 §7.1.2/4 开始:

[...]函数static 中的局部变量extern inline总是引用同一个对象。外部内联函数中的字符串文字是不同翻译单元中的相同对象。

(请注意,extern inline函数是inline具有外部链接的inline函数,即未标记为的函数static。)

它出现在哪个目标文件中将取决于编译器,但我怀疑发生的是每个使用它的目标文件都会得到一个副本,链接器将任意选择一个符号并丢弃其余的。

于 2012-11-08T23:46:41.363 回答
1

该标准保证只使用一份副本。它不能保证不会有未使用的副本占用代码空间。

链接器通常负责合并所有引用以使用相同的实例。

于 2012-11-08T23:41:12.827 回答