这种外在的无害吗?

时间:2009-03-25 19:54:12

标签: c++ c extern

main.h

extern int array[100];

的main.c

#include "main.h"

int array[100] = {0};

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

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

我总是将extern语句可视化为链接器的命令,以“查找实际命名实体的其他位置。它不在此处。

我错过了什么?

感谢。

6 个答案:

答案 0 :(得分:26)

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

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

答案 1 :(得分:9)

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

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

答案 2 :(得分: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 ++中无效。“

答案 3 :(得分:4)

外部是无害和正确的。如果没有extern,你就无法在标题中声明它。

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

#define ARRAY_SIZE 100

extern int array[ARRAY_SIZE];

...

int array[ARRAY_SIZE] = { 0 };

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

答案 4 :(得分:2)

答案 5 :(得分:1)

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

然而,可能危险,因为它使array []可用于#includes main.h的任何其他文件,这可能导致array []的内容在另一个文件中被更改。 / p>

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

如果array []只在main()函数中使用,则在那里声明它。

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