在此提醒,使得它清楚我们正在谈论:
int const a; // illegal
int const a = 42; // definition, internal linkage
extern int const a; // declaration, external linkage
extern int const a = 42; // definition , external linkage
注意,如果没有const
,上述前两个声明是一个具有外部链接都 定义。这只是正交,并不是很直观,但这是现行规则所说的。
与给予一个const外部连接的问题在于,只能有一个 具有外部链接的对象的定义,并且与一个 例外,只有定义可以具有一个初始化。这意味着对于具有外部链接的const的 ,只能在一个 翻译单元中看到实际值(如果 const用于常量表达式,则必需的实际值)。这可能是默认情况下给予const
内部链接的动机。
当然,这不会导致模板问题的结束,理论上至少 ;下面的头有未定义的行为,如果它是 包括在多于一个翻译单元:
#include <std::vector>
int const fixedValue = 42;
inline void insertFixedValue(std::vector<int>& dest)
{
dest.push_back(fixedValue);
}
的标准说不仅必须内联函数和模板具有 令牌相同的序列,但是,所有的符号的必须将 绑定到每个翻译单元中的相同对象,或者存在违反 的一个定义规则。并且由于fixedValue
没有外部连接,因此每个翻译单元中都有一个唯一的实例。 (有 异常如果符号指const
对象和有 立即左值到右值转换。由于 std::vector<int>::push_back
然而通过引用接受其参数, 没有即时左值到右值的转换,我们得到了一个未定义 行为)
和当然,任何人只要有一个模板:
template <int& r> ...
不能实例化它。
内部联动的原因当然是历史性的。今天, 编译器必须能够支持诸如:
struct X
{
static int const a = 42; // declaration!!!, external linkage
};
和功能的各种重复定义。这将是 比较琐碎延长,允许在 声明初始化在命名空间范围类变量的规则,给 类似:
int const a; // illegal
int const a = 42; // definition, external linkage
extern int const a; // declaration, external linkage
extern int const a = 42; // declaration, external linkage
这将恢复正交性(即使它需要额外的输入) 。它 也将打破几乎所有现有的代码。
另一种方法是治疗const
变量定义 完全一样的功能模板今天对待:你可以有多个 定义,但它们都必须是相同的。这大概会避免 大部分(如果不是全部的话)代码破坏。
'extern const a; '不是有效的C++,我不认为。你需要像'extern const' ** int **'a;'你在第一个突出显示的块中有错误,但是在最后一个错误。 – 2014-08-06 19:25:13
@RobertCrovella今天我认为它甚至不是有效的C(如果它是有效的,那肯定是不好的做法)。我修复了它。 – 2014-08-07 08:23:09