外部对象定义和链接 [英] External object definition and linkage
问题描述
经过多年处理定义和关联问题
以我认为安全的方式,我已经决定是时候尝试了
正确理解这个领域。考虑使用
文件范围声明的头文件
int i;
此标题包含在两个中引用i的文件但不是
声明它。这两个文件一起构建成一个程序。
因此在每个翻译单元中声明一次。根据
到C99 6.2.2声明有外部链接并且引用
相同的对象。 6.9.2表示每个声明都是暂定的外部定义,然后转换为实际的外部定义
。现在程序中有2个外部定义i
,这打破了6.9中要求
正好是一个外部定义的要求,因此这导致
未定义的行为。
我有这个权利吗?确认或更正确认。
After many years of dealing with definition and linkage issues
in ways that I know to be safe, I''ve decided it''s time to try
to understand this area properly. Consider a header file with
the file scope declaration
int i;
This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.
i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.
Have I got this right? Confirmation or correction appreciated.
推荐答案
2004年4月2日13:05:42 -0800, jj *@bcs.org.uk (JJ Farrell)写道:
On 2 Apr 2004 13:05:42 -0800, jj*@bcs.org.uk (J. J. Farrell) wrote:
经过多年处理定义和联系问题
我知道的方法是安全的,我已经决定是时候尝试正确理解这个区域了。考虑一个带有文件范围声明的头文件
int i;
这个头文件包含在两个引用i的文件中但是没有
宣布它。这两个文件一起构建成一个程序。
因此我在每个翻译单元中声明一次。根据C99 6.2.2,声明有外部联系并指向同一个对象。 6.9.2表示每个声明都是暂定的外部定义,然后转换为实际的外部定义。程序中现在有2个外部定义,它打破了6.9中的要求,即
应该只是一个外部定义,因此导致未定义的行为。
我做对了吗?确认或更正肯定。
After many years of dealing with definition and linkage issues
in ways that I know to be safe, I''ve decided it''s time to try
to understand this area properly. Consider a header file with
the file scope declaration
int i;
This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.
i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.
Have I got this right? Confirmation or correction appreciated.
6.9.2 / 2的语言是恕我直言,非常含糊不清。这就是(我用
用引号来表示标准中的斜体):
------ -----------
对象的标识符声明,其文件范围没有
初始化程序,并且没有存储类说明符或者使用
存储类说明符static,构成暂定定义。如果
翻译单元包含一个或多个
标识符的暂定定义,并且翻译单元不包含
该标识符的外部定义,然后行为就像翻译单元
包含该标识符的文件范围声明一样,在翻译单元末尾有复合
类型,初始化程序等于0.
----------------
那么那个单词是什么?声明"在倒数第二行做到这一点?如何
可以声明具有初始化器等于0的初始化器。 (或表现为好像它好像b $ b有一个)而不被视为定义。所有
TU'的对象?我不知道。
请注意,这不在约束部分,因此无论是什么
意味着,编译器没有义务生成诊断是否违反了
。所以它实际上可能会说只有一个人应该是b / b
,但如果一个实现带有试探性的话。到了链接
阶段,它可以像有人期望的那样工作(或者习惯它从历史的角度来工作
),这不一定一个不合格的
实施。
[门票:Greg Comeau对此有所帮助,他基本上是
证实了我自己对这一切的困惑。但是我没有想到它不受限制部分的影响...
-leor
-
Leor Zolman --- BD软件--- www.bdsoft.com
C / C ++,Java,Perl和Unix的现场培训
C ++用户:下载BD Software''免费STL错误消息解密器:
www.bdsoft.com/tools /stlfilt.html
" J. J. Farrell写道:
"J. J. Farrell" wrote:
经过多年处理定义和联系问题
以我认为安全的方式,我已经决定是时候尝试
正确理解这个领域。考虑一个带有文件范围声明的头文件
int i;
这个头文件包含在两个引用i的文件中但是没有
宣布它。这两个文件一起构建成一个程序。
因此我在每个翻译单元中声明一次。根据C99 6.2.2,声明有外部联系并指向同一个对象。 6.9.2表示每个声明都是暂定的外部定义,然后转换为实际的外部定义。程序中现在有2个外部定义,它打破了6.9中的要求,即
应该只是一个外部定义,因此导致未定义的行为。
我做对了吗?确认或纠正。
After many years of dealing with definition and linkage issues
in ways that I know to be safe, I''ve decided it''s time to try
to understand this area properly. Consider a header file with
the file scope declaration
int i;
This header is included in two files that refer to i but do not
declare it. The two files build together into a single program.
i is therefore declared once in each translation unit. According
to C99 6.2.2 the declarations have external linkage and refer to
the same object. 6.9.2 says that each declaration is a tentative
external definition, which then gets converted to an actual
external definition. There are now 2 external definitions of i
in the program, which breaks the requirement in 6.9 that there
shall be exactly one external definition, so this results in
undefined behavior.
Have I got this right? Confirmation or correction appreciated.
你是对的。
通常的做法(对于任何外部链接的对象或
函数)是在
头文件中放置一个声明而不是一个定义,并在任何需要的地方#include该标题。
实际定义只存在一个.c文件,其中
本身也是#include'的标题(因此编译器可以抱怨
如果声明和定义不一致)。
在你的情况下,标题会说
extern int i;
....其中extern大致意思是这只是一个声明;
在其他地方有一个匹配的定义。对于一个函数
你可以说
extern int func(void);
....除外事实证明,extern这是不必要的(尽管
无害):编译器可以告诉它'不是定义
因为没有`{...}''函数最后一点:很多人都认为全局变量
是坏的,主要是因为它们可以创建难以看清的耦合
在程序中显然不相关的部分之间。我不太喜欢他们比一些居民强烈反对他们,但每当我把一个全局变量加入我的程序时我就会停止
并考虑这是否真的是*正确的事情。
很多时候,它不是。
-
< a href =mailto:Er ********* @ sun.com> Er ********* @ sun.com
2004年4月2日星期五18:31:34 -0500,Eric Sosman< Er ********* @ sun.com>
写道:
On Fri, 02 Apr 2004 18:31:34 -0500, Eric Sosman <Er*********@sun.com>
wrote:
通常的做法(对于任何外部链接的对象或
函数)是在
头文件中放置声明而不是定义,并在任何需要的地方#include那个标题。
实际的定义只有一个.c文件,它本身也是#include'的标题(因此编译器可以抱怨)
如果声明和定义不一致)。
在你的情况下,标题会说
extern int i;
...其中extern大致意思是这只是一个声明;
在其他地方有一个匹配的定义。
The usual practice (for any externally-linked object or
function) is to put a declaration, not a definition, in a
header file, and to #include that header wherever it''s needed.
The actual definition goes in one and only one .c file, which
itself also #include''s the header (so the compiler can complain
if the declaration and the definition disagree).
In your case, the header would say
extern int i;
... where "extern" means, roughly, "this is just a declaration;
there''s a matching definition somewhere else."
作为我平常的字面意思 - 自我,我回答了OP的具体问题
我能做到的最好......但现在我觉得有必要补充一点,Eric说的方式
做的事情是当然/右/方式设置TU间链接,因为它b / b
是完全明确的,在C和C ++中都是一样的。
试图理解int i;的情况。出现在文件范围内
多个TU'似乎更好地留在标准
解密中练习,并且可能不应该被允许变成实用问题
;-)
-leor
-
Leor Zolman --- BD软件--- www.bdsoft.com
现场C / C ++,Java,Perl和Unix培训
C ++用户:下载BD Software的免费STL错误消息解密器:
www.bdsoft.com/tools/stlfilt.html
这篇关于外部对象定义和链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!