c - 头文件中没有 extern 的全局变量

标签 c declaration storage-class-specifier

在头文件中使用全局变量,我们可以在另一个文件中更改值/使用变量(相同的值可以在多个文件中访问/修改),那么为什么可以使用 extern ?全局 和 外部 和有什么不一样?

下面是我尝试过的示例,它在 c 中的外部变量和全局变量没有区别。

程序编译运行成功,没有任何错误。

t.h

int i;

t1.c

#include<stdio.h>
#include "t.h"

int main()
{
        i=10;
        printf("%s i = %d\n",__func__, i);
        t2();
        printf("%s i = %d\n",__func__, i);
        i=200;
        printf("%s i = %d\n",__func__, i);
        t3();
        printf("%s i = %d\n",__func__, i);

return 0;
}

t2.c

#include<stdio.h>
#include "t.h"

void t2()
{
        printf("%s i=%d\n",__func__, i);
        i = 100;
        printf("%s i=%d\n",__func__, i);
}

t3.c

#include<stdio.h>
#include "t.h"

void t3()
{
        printf("%s i=%d\n",__func__, i);
        i = 300;
        printf("%s i=%d\n",__func__, i);
}

输出:- gcc t1.c t2.c t3.c

main i = 10
t2 i=10
t2 i=100
main i = 100
main i = 200
t3 i=200
t3 i=300
main i = 300

最佳答案

参见C11 6.9.2p2

A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition.

这就是您所拥有的:暂定定义

尝试文件 t.h 的不同变体

int i;
int i = 42;
static int i;
static int i = 42;
extern int i;

各种说明options at gcc documentation可能有帮助

-fno-common

In C code, this option controls the placement of global variables defined without an initializer, known as tentative definitions in the C standard. Tentative definitions are distinct from declarations of a variable with the extern keyword, which do not allocate storage.

Unix C compilers have traditionally allocated storage for uninitialized global variables in a common block. This allows the linker to resolve all tentative definitions of the same variable in different compilation units to the same object, or to a non-tentative definition. This is the behavior specified by -fcommon, and is the default for GCC on most targets. On the other hand, this behavior is not required by ISO C, and on some targets may carry a speed or code size penalty on variable references.

The -fno-common option specifies that the compiler should instead place uninitialized global variables in the BSS section of the object file. This inhibits the merging of tentative definitions by the linker so you get a multiple-definition error if the same variable is defined in more than one compilation unit. Compiling with -fno-common is useful on targets for which it provides better performance, or if you wish to verify that the program will work on other systems that always treat uninitialized variable definitions this way.

关于c - 头文件中没有 extern 的全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57323275/

相关文章:

c - 在句子中按字母顺序对字符串中的字符进行排序

c - fread 和 fwrite 的问题

C 用strcpy修改char**

kubernetes - storageclass reclaimPolicy vs pv reclaimPolicy

c - GLSL:片段着色器计数 'out' s

java - Eclipse - 根据返回或获取声明变量(快捷方式)

C++ 错误 C2662 或如何以正确的方式声明

java - 文档中的 dom4j XML 声明

c - 为什么寄存器数组名称可以分配给指针变量而不会出现编译器错误?