外部声明中的警告

时间:2010-11-25 06:06:30

标签: c

我在temp2.​​h中声明了一个变量i  extern i;只包含一行 并制作了另一个文件 temp3.c

 #include<stdio.h>
#include<temp2.h>
int main ()
{
extern i;
i=6;
printf("The i is %d",i);
}

当我在上面编译为  cc -I ./ temp3.c我收到了以下错误

 /tmp/ccJcwZyy.o: In function `main':
temp3.c:(.text+0x6): undefined reference to `i'
temp3.c:(.text+0x10): undefined reference to `i'
collect2: ld returned 1 exit status

我已经在上面的temp3.c中声明了extern,正如我在上面的文章中所提到的那样,K R第33页说。 我为temp3.c尝试了另一种方法,使用相同的头文件temp2.​​h

 #include<stdio.h>
#include<temp2.h>
int main ()
{

i=6;
printf("The i is %d",i);
}

并将其编译为cc -I ./ temp3.c并出现以下错误

/tmp/ccZZyGsL.o: In function `main':
temp3.c:(.text+0x6): undefined reference to `i'
temp3.c:(.text+0x10): undefined reference to `i'
collect2: ld returned 1 exit status

我也试过

 #include<stdio.h>
#include<temp2.h>
int main ()
{
extern i=6;
printf("The i is %d",i);
} 

编译了这个

 cc -I ./ temp3.c

与第1篇中的错误相同

 temp3.c: In function ‘main’:
temp3.c:5: error: ‘i’ has both ‘extern’ and initializer

所以我尝试了至少3种不同的方法来使用extern但不使用它们。

3 个答案:

答案 0 :(得分:14)

当您使用extern声明变量时,您告诉编译器变量是在别处定义的,并且定义将在链接时提供。包容是完全不同的。

extern

  

外部变量必须在任何函数之外定义一次;这为它预留了存储空间。必须在每个想要访问它的函数中声明变量;这说明了变量的类型。声明可能是一个明确的外部声明,也可能是隐含在上下文中的。

     

- C编程语言

必须在程序的一个模块(在其中一个翻译单元中)定义一个变量。如果没有定义或多个定义,则可能会在链接阶段中产生错误(如示例1和2中所示)。

尝试类似以下内容

a.c

int i =10; //definition

b.c

extern int i; //declaration
int main()
{
    printf("%d",i);
}

使用

编译,链接和创建可执行文件
gcc a.c b.c -o executable_name


gcc -c a.c // creates a.o
gcc -c b.c // creates b.o

现在链接目标文件并创建可执行文件

gcc a.o b.o -o executable_name

答案 1 :(得分:4)

第一个节目说:

  • 变量i(隐含式int)在其他地方定义 - 但您没有在任何地方定义它。

第二个程序试图使用一个根本没有声明的变量。

第三个程序试图声明一个没有显式类型的变量(以前是正常的;在C99中不允许),并说:

  • 变量i在其他地方定义,但我想在这里初始化它。

你不被允许这样做。

因此,编译器在所有情况下都是正确的。


标题'temp2.​​h'中的声明应首先固定为extern int i;。隐式int已经过时了。

您可以通过多种方式修复第一个示例:

#include <stdio.h>
#include <temp2.h>
int main()
{
    extern int i;
    i=6;
    printf("The i is %d",i);
    return 0;
}

int i;

这定义了函数之后的变量 - 常规但合法。它也可以在一个单独的源文件中,该文件是单独编译的,然后与主程序链接。

第二个例子可以修复:

#include <stdio.h>
#include <temp2.h>
int main()
{
    int i=6;
    printf("The i is %d",i);
    return 0;
}

重要的是要注意,此示例现在有两个名为i的变量;在temp2.h中声明的那个(但实际上没有在任何地方引用),以及main()中定义的那个。修复它的另一种方法与第一个可能的修复相同:

#include <stdio.h>
#include <temp2.h>
int main()
{
    i=6;
    printf("The i is %d",i);
    return 0;
}

int i;

再次,传统的安置,但合法。

第三个可以通过类似的方法修复前两个,或者这个变体:

#include <stdio.h>
#include <temp2.h>
int i;
int main()
{
extern int i;
i=6;
printf("The i is %d",i);
return 0;
}

这仍在i中声明<temp2.h>,但在包含main()的源文件中定义它(通常放置在文件的顶部)。 extern int i;内部main()是双重冗余的 - 源文件中的定义和标头中的声明意味着它不需要在main()内重新声明。请注意,通常,标头中的声明和源文件中的定义不是多余的;标头中的声明提供了与定义的一致性检查,然后确保使用变量和标头的其他文件,包含main()的文件中的定义等同于另一个文件的定义也用。

答案 2 :(得分:2)

extern是一种声明机制,用于告诉编译器该变量是在另一个文件中定义的。

我的建议是你在“.c”文件中定义一个变量,然后在相应的“.h”文件中添加extern声明。通过这种方式,变量声明将可用于包含此头文件的所有源文件,并且更容易识别实际定义的“.c”。

相关问题