关于外部的混淆与C中的函数定义

smi*_*ley 9 c

可能重复:
`extern`关键字对C函数的影响

好的,现在几个小时我已经阅读了很多关于extern关键字的含义.还有最后一件事让我无所事事,我无法找到任何相关信息.据我所知,extern关键字基本上告诉编译器变量或函数只是一个声明,并且它是在某处定义的,因此它不必担心,链接器将处理它.

输入以下内容时编译器生成的警告(我正在使用gcc 4.2.1):

extern int var = 10;
Run Code Online (Sandbox Code Playgroud)

支持这个.有了extern这应该是唯一的,因此是不正确的声明.

然而,令我困惑的是在键入此内容时没有警告或任何内容:

extern int func() {return 5;}
Run Code Online (Sandbox Code Playgroud)

这是一个定义,它应该生成相同的警告,但事实并非如此.我在这里找到的唯一解释是该定义覆盖了extern关键字.但是,遵循该逻辑,为什么它不是在变量定义时覆盖它?或者当与变量一起使用时,关键字是否具有特殊含义?

如果有人向我解释,我将非常感激.谢谢!

das*_*ght 5

extern关键词的确只有当它被用来与变量特殊的意义.使用extern函数原型完全是可选的:

extern void foo(int bar);
Run Code Online (Sandbox Code Playgroud)

相当于

void foo(int bar);
Run Code Online (Sandbox Code Playgroud)

声明/定义函数时,有两个选项:

  1. 仅提供声明(即原型),或
  2. 提供一个定义,在没有原型的情况下也可以作为声明.

但是,对于变量,您有三个选项:

  1. 只提供声明,
  2. 使用默认初始化程序提供定义:int var;没有= 10部分,或
  3. 提供具有特定初始值设定项的定义: int var = 10

由于函数只有两个选项,因此编译器可以在不使用extern关键字的情况下进行区分.默认情况下static会考虑任何没有关键字的声明extern.因此,extern关键字将被所有函数声明或定义忽略.

但是,对于变量,需要使用关键字来区分#1和#2.使用时extern,它是#1; 当你不使用时extern,它是#2.当您尝试添加extern到#3时,它是一个警告,因为它仍然是一个定义,并被extern忽略.

所有这些都有些简化:您可以在同一个编译单元中多次提供声明,并且可以在全局范围或块范围内提供它们.有关完整的详细信息,请查看C标准的6.7.9 5部分.