在C99和链接暂定定义 [英] Tentative definitions in C99 and linking

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

问题描述

考虑的两个文件组成的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 定义,但是这是我的跨pretation暂定定义成为在翻译单元的最后一个实际的定义,以及(在我看来),因此应该表现为,如果在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.

这个有什么想法?该标准的其他跨pretations?平台名称上的文件在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 extern变量见。这在资料附录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关键字 - 不是一个严格符合程序,并且不保证工作无处不在。等价的:它包含的错误这可能会或可能不会显示自己

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.

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

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