为什么'的extern“存储类的工作方式不同的功能呢? [英] Why 'extern' storage class works differently in functions?

查看:221
本文介绍了为什么'的extern“存储类的工作方式不同的功能呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码片段正常工作

The following snippet works fine

extern int i;
int i;

int main(){
    return 0;
}

下面我得到了什么是'我'的声明,然后定义。由于只有一个定义因此多数民众赞成完美的罚款。

Here what I got is, 'i' is declared and then defined. Since there is only one definition so thats perfectly fine.

int main(){
    extern int i;
    int i;
    return 0;
}

现在,上面的人给了以下错误

Now, the above one gives the following error

new.cpp: In function ‘int main()’:
new.cpp:5:6: error: redeclaration of ‘int i’
  int i;
      ^
new.cpp:4:13: note: previous declaration ‘int i’
  extern int i;

请告诉我这里的问题?这里也有'我'一个统一的定义。

Whats the problem here? Here also there is single definition of 'i'.

推荐答案

要理解上的差异,你需要熟悉一个叫C.概念的暂定定义的引述C标准:

To understand the difference, you need to get familiar with a concept called tentative definition in C. To quote the C standard:

C11,草案§6.9.2,外部对象定义

有关对象标识符的声明有文件范围内
  没有初始化,并且没有存储类说明或
  存储类说明静,构成了暂定
  定义。如果一个翻译单元包含一个或多个暂定
  的标识符定义和翻译单元包含无
  该标识符外部定义,则行为是完全
  仿佛翻译单元包含一个文件范围内声明
  标识符,与复合型作为翻译的端部的
  单位,等于0的初始化。

A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.

您在第一个片段是什么只对 A暂定定义I 。你可以有很多的暂定定义为一个对象,你想要的(但只有一个定义是允许的):

What you have in the first snippet is only a tentative definition for i. You can have as many tentative definitions for an object as you want (but only one definition is allowed):

int i; // tentative definition
int i; // tentative definition
int i; // tentative definition

int main(void) {
   return 0;
}

是有效的。

在这里, I 有外部链接,并初步确定。如果 I 在同一个翻译单元的地方被定义,那么这将是的实际定义我。如果有没有其他的定义 I 在翻译单元被发现,那么这个就好像它是像定义的完整定义:

Here, i has external linkage and tentatively defined. If i is defined in somewhere in the same translation unit, then that'll be the actual definition of i. If there's no other definition of i is found in the translation unit, then this becomes the full definition as if it was defined like:

int i = 0;

int main(void) {
   return 0;
}

但第二个片段 INT I; 是的的一个试探性的定义。只有外部链接的对象可以暂时定义。在第二个片段中,声明的extern INT I; 表示, I 与外部链接的其他地方定义。但下一行 INT I; 表示, I 与没有任何联系(本地自动变量没有任何联系定义 - - 这是的的暂定定义)。所以这是定义为 I 的冲突。因此,第一个片断是好的,但第二个不是。

But the second snippet int i; is not a tentative definition. Only objects with external linkage can be defined tentatively. In second snippet, The declaration extern int i; says i is defined elsewhere with external linkage. But the next line int i; says i is defined with no linkage (local automatic variables do not have any linkage -- this is not a tentative definition). So there's a conflict of definition for i. Hence, the first one snippet is fine but second isn't.

这篇关于为什么'的extern“存储类的工作方式不同的功能呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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