给定一个源文件
int a = 1;
和另一个源文件
int a = 1;
int main() { }
实现通常会拒绝这一点,这对我来说很有意义,即使a
未被使用。
但是,我无法找到标准所说的错误。
在C中,这是(强调我的):
6.9外部定义
5 外部定义是一个外部声明,它也是函数(内联定义除外)或对象的定义。如果在表达式中使用通过外部链接声明的标识符(除了作为
sizeof
运算符的操作数的一部分,其结果是整数常量),则整个程序中的某个地方应该只有一个外部定义。标识符; 否则,不得超过一个。
由于这出现在约束之外,在C中,行为只是未定义。允许实现拒绝它,或者允许它们在没有警告的情况下默默地接受它,在这种情况下不保证对该行为的保证。我非常确定C ++的意图是一样的。
我能够找到相应的"在整个程序的某处,只有一个外部定义的标识符"在[basic.def.odr]的C ++标准中:
3.2一个定义规则[basic.def.odr]
4每个程序应该只包含该程序中使用的每个非内联函数或变量的一个定义;无需诊断。 [...]
但是,我无法找到涵盖非常用的对象或功能的措辞。标准是否指定这是一个错误的任何地方?如果是这样,在哪里?
[basic.def.odr]还包含对p6中通常可以有多个定义的某些类型实体的限制,有效地说明所有定义必须相同。但这仅涵盖"类类型(第9条),枚举类型(7.2),带外部链接的内联函数(7.1.2),类模板(第14条),非静态函数模板(14.5.6) ,类模板的静态数据成员(14.5.1.3),类模板的成员函数(14.5.1.1),或未指定某些模板参数的模板特化(14.7,14.5.5)",不全局变量,此外,定义匹配。
我怀疑[dcl.link]可以解决这个问题,但事实并非如此,它最接近的是关于C链接的实体的注释,它只是引用回[basic.def.odr]: / p>
7.5链接规范[dcl.link]
6 [...] [注意:程序中可能只出现具有C语言链接名称的实体的一个定义(见3.2);这意味着不得在多个命名空间范围内定义此类实体。 - 结束记录] [...]
我几乎可以肯定我只是忽略了某些东西,因为这显然是一个错误。