5

主文件

extern int array[100];

主程序

#include "main.h"

int array[100] = {0};

int main(void)
{
    /* do_stuff_with_array */ 
}

在 main.c 模块中,定义并声明了数组。将 extern 语句也包含在模块中的行为是否会导致任何问题?

我一直将 extern 语句可视化为链接器的命令,以“在其他地方查找实际的命名实体。它不在这里。

我错过了什么?

谢谢。

邪恶的。

4

5 回答 5

26

正确的解释extern是你告诉编译器一些事情。您告诉编译器,尽管声明的变量现在不存在,但链接器会以某种方式找到声明的变量(通常在另一个对象(文件)中)。链接器将是找到所有内容并将其组合在一起的幸运者,无论您是否有一些外部声明。

为了避免在特定对象(文件)之外暴露名称(变量、函数、..),您必须使用static.

于 2009-03-25T19:58:52.800 回答
9

是的,它是无害的。事实上,我会说这是一种非常标准的方式来做你想做的事。

如您所知,这只是意味着任何包含 main.h 的 .c 文件也将能够查看array和访问它。

于 2009-03-25T19:54:56.523 回答
6

编辑

在 C 和 C++ 中,存在extern表示第一个声明不是定义。因此,它只是使名称在当前翻译单元(包括标题的任何人)中可用,并表明所引用的对象具有外部链接 - 即在构成程序的所有翻译单元中都可用。这并不是说该对象必然位于另一个翻译单元中——只是说“这条线不是定义”。

结束编辑

在 C 中,extern是可选的。没有它,第一个声明就是一个“暂定定义”。如果不是为了后面的定义(因为它有一个初始化器,这是一个明确的定义),这将被视为一个定义(C99 6.9.2)。事实上,它只是一个声明,并不冲突。

在 C++ 中,extern不是可选的 - 没有它,第一个声明是与第二个冲突的定义 (C++03 3.1)。

在 C++ 的附件 C 中明确指出了这种差异:

“更改:C++ 没有 C 中的“暂定定义”

例如,在文件范围内,

int i;
int i;

在 C 中有效,在 C++ 中无效。”

于 2009-03-25T22:46:46.763 回答
4

外部是无害且正确的。如果没有 extern,您将无法在标头中声明它。

另外,通常最好的做法是创建一个宏或一个常量来保存数组的大小;在您的代码中,实际大小(100)在源代码库中出现两次。这样做会更干净:

#define ARRAY_SIZE 100

extern int array[ARRAY_SIZE];

...

int array[ARRAY_SIZE] = { 0 };

但也许你不想为了简洁起见将它包含在代码片段中,所以请不要冒犯:)

于 2009-03-25T20:46:46.617 回答
1

从编译或执行的角度来看,它没有区别。

但是,它具有潜在的危险,因为它使 #includes main.h 的任何其他文件都可以使用 array[],这可能导致 array[] 的内容在另一个文件中被更改。

因此,如果 array[] 只在 main.c 中使用,请从 main.h 中删除该行,并在 main.c 中将 array[] 声明为静态。

如果 array[] 仅用于 main() 函数,则在其中声明它。

换句话说,array[] 应该将其范围限制在尽可能小的范围内。

于 2009-03-28T15:59:00.527 回答