4

给定一个源文件

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 每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的准确定义;无需诊断。[...]

但是,我找不到涵盖未使用 odr 的对象或功能的措辞。标准是否在任何地方指定这是一个错误?如果有,在哪里?

[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]:

7.5 联动规范 [dcl.link]

6 [...] [注:程序中只能出现一个具有给定名称的实体的定义和 C 语言链接(见 3.2);这意味着这样的实体不得在多个命名空间范围内定义。--尾注] [...]

我几乎可以肯定我只是忽略了一些东西,因为很明显这是一个错误。

4

0 回答 0