C和链接中的暂定定义 [英] Tentative definitions in C and linking

查看:80
本文介绍了C和链接中的暂定定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑由两个文件组成的C程序,

Consider the C program composed of two files,

f1.c:

int x;

f2.c:

int x=2;

我对 C99标准在于该程序应被拒绝。在我对6.9.2的解释中,变量 x 是在 f1.c 中临时定义的,但是这个临时定义变成了因此,翻译单元末尾的实际定义(并且,我认为)应该像 f1.c 包含定义 int x = 0;

My reading of paragraph 6.9.2 of the C99 standard is that this program should be rejected. In my interpretation of 6.9.2, variable x is tentatively defined in f1.c, but this tentative definition becomes an actual definition at the end of the translation unit, and (in my opinion), should therefore behave as if f1.c contained the definition int x=0;.

使用所有编译器(而且重要的是链接器),我都可以尝试,但事实并非如此。我尝试过的所有编译平台都链接了上述两个文件,两个文件中 x 的值均为2。

With all compilers (and, importantly, linkers) I was able to try, this is not what happens. All compilation platforms I tried do link the above two files, and the value of x is 2 in both files.

我怀疑这是偶然发生的,还是只是标准需要提供的简便功能。如果您考虑一下,这意味着链接器中特别支持那些没有初始化程序的全局变量,与那些明确初始化为零的全局变量相反。有人告诉我,无论如何编译Fortran可能都需要链接器功能。

I doubt this happens by accident, or just as an "easy" feature to provide in addition to what the standard requires. If you think about it, it means there is special support in the linker for those global variables that do not have an initializer, as opposed to those explicitly initialized to zero. Someone told me that the linker feature may be necessary to compile Fortran anyway. That would be a reasonable explanation.

对此有何想法?标准的其他解释? f1.c f2.c 拒绝链接到的平台的名称?

Any thoughts about this? Other interpretations of the standard? Names of platforms on which files f1.c and f2.c refuse to be linked together?

注意:这很重要,因为问题是在静态分析的上下文中发生的。如果两个文件可能拒绝在某个平台上链接,则分析器应该投诉,但是如果每个编译平台都接受它,则没有理由对其进行警告。

Note: this is important because the question occurs in the context of static analysis. If the two files may refuse to be linked on some platform, the analyzer should complain, but if every compilation platform accepts it then there is no reason to warn about it.

推荐答案

另请参见什么是C语言中的外部变量。在信息性附录J的C标准中,这是一个通用扩展名。

See also What are extern variables in C. This is mentioned in the C standard in informative Annex J as a common extension:


J.5.11多个外部定义

J.5.11 Multiple external definitions

在有或没有明确使用关键字extern的情况下,一个对象的标识符可能有多个外部定义;如果定义不同意,或者初始化了多个定义,则行为未定义(6.9.2)。

There may be more than one external definition for the identifier of an object, with or without the explicit use of the keyword extern; if the definitions disagree, or more than one is initialized, the behavior is undefined (6.9.2).


警告


正如@litb在这里指出的那样,正如我在对交叉引用问题的回答中所指出的那样,对全局变量使用多个定义会导致未定义的行为,这是标准所说的可能发生的一切的方式。可能发生的事情之一是该程序的行为符合您的预期。 J.5.11大约说:您可能比应有的机会更幸运。但是,依赖于extern变量的多个定义(带有或不带有显式的 extern关键字)的程序,并不是严格符合要求的程序,并且不能保证在任何地方都能正常工作。等效:它包含一个错误,该错误可能会显示也可能不会显示。

Warning

As @litb points out here, and as stated in my answer to the cross-referenced question, using multiple definitions for a global variable leads to undefined behaviour, which is the standard's way of saying "anything could happen". One of the things that can happen is that the program behaves as you expect; and J.5.11 says, approximately, "you might be lucky more often than you deserve". But a program that relies on multiple definitions of an extern variable - with or without the explicit 'extern' keyword - is not a strictly conforming program and not guaranteed to work everywhere. Equivalently: it contains a bug which may or may not show itself.

这篇关于C和链接中的暂定定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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