关于C中函数定义与外部的混淆
可能重复:关于C中函数定义与外部的混淆,c,C,可能重复: 好的,几个小时以来我读了很多关于extern关键字的意思。还有最后一件事一直困扰着我,我找不到任何信息。 据我所知,extern关键字基本上告诉编译器变量或函数只是一个声明,它是在某个地方定义的,因此它不必担心这一点,链接器将处理它 以及编译器(我使用gcc 4.2.1)在键入以下内容时生成的警告: extern int var = 10; extern int func() {return 5;} 支持这一点。对于extern这应该是一个声明,因此它是不正确的 然而,让我困惑
好的,几个小时以来我读了很多关于extern关键字的意思。还有最后一件事一直困扰着我,我找不到任何信息。 据我所知,
extern
关键字基本上告诉编译器变量或函数只是一个声明,它是在某个地方定义的,因此它不必担心这一点,链接器将处理它
以及编译器(我使用gcc 4.2.1)在键入以下内容时生成的警告:
extern int var = 10;
extern int func() {return 5;}
支持这一点。对于extern
这应该是一个声明,因此它是不正确的
然而,让我困惑的是,键入以下内容时没有警告或任何内容:
extern int var = 10;
extern int func() {return 5;}
这是一个定义,它应该生成相同的警告,但它没有。我在这里能找到的唯一解释是定义覆盖了extern
关键字。然而,遵循这个逻辑,当它是一个变量定义时,为什么不重写它呢?或者,当与变量一起使用时,关键字是否具有特殊意义
如果有人向我解释这一点,我将不胜感激。谢谢大家!
然而,遵循这个逻辑,当它是一个变量定义时,为什么不重写它呢?或者,当与变量一起使用时,关键字是否具有特殊意义
变量和函数之间的区别在于
void foo();
是一个函数声明,但是
int i;
是一个变量定义。
如果在多个文件中有变量定义,那么编译器将多次为该变量生成存储(很可能会出现链接器错误)。函数不是这样。关键字
extern
只有在与变量一起使用时才具有特殊意义。对函数原型使用extern
是完全可选的:
extern void foo(int bar);
相当于
void foo(int bar);
声明/定义函数时,有两个选项:
int-var代码>不带=10
部分,或
int var=10
extern
关键字的情况下区分它们。默认情况下,没有静态
关键字的任何声明都被视为外部
。因此,所有函数声明或定义都会忽略extern
关键字
但是,对于变量,需要使用关键字来区分#1和#2。当您使用extern
时,它是#1;当您不使用extern
时,它是#2。当您尝试将extern
添加到#3时,这是一个警告,因为它仍然是一个定义,而extern
将被忽略
所有这些都有些简化:您可以在同一个编译单元中多次提供声明,并且可以在全局范围或块范围中提供声明。有关完整的详细信息,请查看C标准的第6.7.9.5节。最后一个分号让我感到困扰。请查看是否有帮助。问题必须是变量的初始化。虽然此问题名义上是重复的,但建议的原始答案质量较低。它过于冗长、不清楚、不完全准确,并且提供了不相关的误导性建议代码>看起来既像一个声明,又像一个带有初始值设定项的定义是一个暂定定义,不是定义,它既不会多次生成存储,也不会导致链接错误。有关对象(非变量)声明的语句不正确。在文件范围:
intx
是具有外部链接的对象的暂定定义,extern intx
是具有外部链接的对象的声明,intx=3代码>和extern int x=3代码>都是具有外部链接的对象的定义。在块范围内:intx
是一个没有链接的对象定义,extern int x
是具有外部链接的对象的声明,intx=3
是没有链接的对象的定义,并且extern int x=3根据C 2011 6.7.9 5,代码>是不允许的……以上假定每个声明都是标识符第一次出现在该范围内。否则,就会出现并发症。例如,static int x;外部INTX允许使用code>,后者x
与前者x
相同。此外,尽管有些编译器发出警告,提示extern int x=3
在文件范围内,它在C 2011 6.9.2 4的示例中显式显示为有效。@EricPostSchil我编辑了答案,感谢您的评论。