假设我有两个文件:
==文件1==
extern char* foo;
==文件2==
double foo;
尽管类型不匹配,这两个文件似乎可以很好地编译和链接 g++ 和 clang++。据我了解,推荐的做法是将 extern 声明放在两个文件都包含的 header 中,这样 File2 将引发重新定义错误。
我的问题是:
- 根据 c++ 标准,这会导致未定义的行为吗?如果不是,File1 中的 foo 是什么?
- 链接器能否捕捉到这种类型不匹配?
最佳答案
Does this result in undefined behavior according to the c++ standard?
好吧,真正的问题是这是否是未定义的行为,或者它是否被标准指定为格式错误(用标准的说法)。因为,显然,这是不正确的。我试图从标准中找到关于此的内容,但无济于事。然而,在许多类似的情况下,例如 decl/def 的不匹配或在链接器上抛出奇怪的东西(参见第 3.5、7.5 节,或搜索“extern”或“linkage”),标准通常最终会说:
程序格式错误,无需诊断。
所以,我敢打赌,这里的情况也是如此。这将意味着这是错误的代码,比“未定义的行为”更糟糕,因为 UB 通常会对特定实现具有某种合理的行为(尽管您不应该推测该行为是什么,当然也不应该依赖于它猜测)。 “格式错误”一词在标准中的使用非常自由,您或多或少可以推断出它意味着代码是 FUBAR。这也意味着按照标准,链接器不需要以允许它捕获此类错误的方式实现,这就是它编译和链接正确的原因,但在运行它时请捕获你的 socks .
Could linkers catch this kind of type mismatch?
理论上,是的。链接器实现可以将变量的类型编码(使用名称修改)到它的外部符号中,因此能够限制链接到类型匹配的事物(例如,像重载函数),或者在以下情况下抛出诊断(错误)它遇到类型不匹配。我认为与标准相比,前者过于宽松。
但是,我所知道的所有编译器都不会破坏变量的名称,因此,您可以假设这种不匹配是“格式错误,无需诊断”。
关于c++ - 当 extern 声明和定义之间存在不匹配的类型时会出现什么行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14697698/