当extern声明和定义之间存在不匹配的类型时,行为是什么? [英] What is the behavior when there are mismatched types between an extern declaration and the definition?

查看:550
本文介绍了当extern声明和定义之间存在不匹配的类型时,行为是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有两个文件:



== File1 ==

  extern char * foo; 

== File2 ==

  double foo; 

这两个文件似乎编译和链接只是罚款与g ++和clang ++尽管类型不匹配。我理解它的推荐做法是将extern声明放在一个头文件中,这两个文件都包括所以File2将抛出一个重新定义错误。



我的问题是:




  • 这是否会导致根据c ++标准的未定义行为?如果不是File1中的 foo 内容?

  • 可能是链接器遇到这种类型不匹配?


解决方案


根据c ++标准,这会导致未定义的行为吗?


那么,真正的问题是,这是否是未定义的行为或者它是否被标准定义为不成立在标准用语)。因为,显然,它是不正确的。我试图从标准中找到一些关于这一点,但没有效果。然而,在许多类似的情况下,例如,在链接器(参见第3.5,7.5节,或搜索extern或链接),decl / def或抛出有趣的东西不匹配,标准通常最后说: / p>

这个程序是错误的,无需诊断。



所以,我敢打赌,这也是这种情况。这意味着这是错误的代码,比未定义的行为更糟糕,因为UB通常会对某个特定的实现有一些合理的行为(虽然你不应该猜测这个行为是什么,推测)。 不良形式术语在标准中非常自由地使用,你可以或多或少地推断它意味着代码是FUBAR。这也意味着,标准不需要链接器以允许它捕获这种错误的方式实现,这就是为什么它编译和链接正确,但是当你运行它的时候坚持你的袜子


可能是连结接受这种类型的不配对吗?


理论上,是的。链接器实现可以将变量的类型编码为其外部符号,并且因此能够限制链接到类型匹配的东西(例如,像重载函数),或者在发生错误时抛出诊断(错误)它遇到不匹配的类型。我认为前者比标准过于宽容。



但是,我知道的所有编译器不会改变变量的名称,因此,可以假设这样的错配是形成不良,无需诊断。


Suppose I have two files:

==File1==

extern char* foo;

==File2==

double foo;

These two files seem to compile and link just fine with both g++ and clang++ despite the type mismatch. As I understand it the recommended practice is to put the extern declaration in a header which both files include so File2 will throw a redefinition error.

My questions are:

  • Does this result in undefined behavior according to the c++ standard? If not what goes in foo in File1?
  • Could linkers catch this kind of type mismatch?

解决方案

Does this result in undefined behavior according to the c++ standard?

Well, the real question is whether this is undefined behavior or whether it is specified by the standard as being ill-formed (in standard parlance). Because, obviously, it is not correct. I have tried to find something from the standard about this, but to no avail. However, in a number of similar situations, e.g., mismatches of decl/def or throwing funky things at the linker (see section 3.5, 7.5, or search for "extern" or "linkage"), the standard generally ends up saying:

The program is ill-formed, no diagnosis required.

So, I would bet it's pretty safe to assume this is the case here too. This would mean that this is erroneous code, worst than "undefined behavior", since UB often will have some kind of reasonable behaviour for a specific implementation (although you shouldn't speculate on what that behaviour would be, and certainly not rely on that speculation). The "ill-formed" term is used very liberally in the standard, and you can more or less infer that it means that the code is FUBAR. This would also mean that the linker is not required, by the standard, to be implemented in a way that allows it to catch this kind of error, and that's why it compiles and links correctly, but hold on to your socks when you run it.

Could linkers catch this kind of type mismatch?

In theory, yes. A linker implementation could encode (with name-mangling) the type of the variable into its external symbol, and thus be able to either restrict linkage to things whose types match (e.g., like overloaded functions), or throw a diagnosis (error) when it encounters a mismatch in types. I think that the former would be too permissive as compared to the standard.

However, all compilers that I know of do not mangle the names of variables, and thus, you can assume that such a mismatched is "ill-formed, no diagnosis required".

这篇关于当extern声明和定义之间存在不匹配的类型时,行为是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆