C语言中全局变量初始化的重要性!!!
2013-04-17 17:14
387 查看
在C语言里,全局变量如果不初始化的话,默认为0,也就是说在全局空间里:
int x =0; 跟 int x; 的效果看起来是一样的。但其实这里面的差别很大,强烈建议大家所有的全局变量都要初始化,他们的主要差别如下:
编译器在编译的时候针对这两种情况会产生两种符号放在目标文件的符号表中,对于初始化的,叫强符号,未初始化的,叫弱符号。
连接器在连接目标文件的时候,如果遇到两个重名符号,会有以下处理规则:
1、如果有多个重名的强符号,则报错。
2、如果有一个强符号,多个弱符号,则以强符号为准。
3、如果没有强符号,但有多个重名的弱符号,则任选一个弱符号。
基于以上规则看下面的程序:(编译器为gcc 3.4.6, VC下结果不一样)
因为两个文件里面的x都被初始化了,所以编译出来的两个目标文件里x都是强符号,连接的时候会报错:
multiple definition of `x'
符合规则1。
把var.c里面的int x = 0;改成 int x; 不做初始化,编译、连接无任何警告,运行结果为:
x:1
x:2
说明连接的时候以main.c中的x为准,foo函数修改的是main.c中定义的x。符合规则2。
把main.c中的初始化也去掉,改成 int x; 编译、连接仍然很顺利,运行结果为:
x:0
x:2
说明main函数和foo函数修改的是同一个x,连接器自己选择了一个x,符合规则3.
大部分情况下,我们不希望连接器为我们做决定,所以我不是很认同后两个规则,至少应该给个警告,而不应该安静地通过。
也许写var.c的人根本不知道main.c里面也有一个x呢,foo函数的本意也许并不是要修改main.c中的x。因为这种问题引起的bug会很难查。
所以我们要尽量把全局变量初始化,对于不想给别的文件引用的变量,也尽量用static修饰。
除了连接时的表现不一样外,未初始化的符号在目标文件的bss段中,而初始化的符号在data段中。
int x =0; 跟 int x; 的效果看起来是一样的。但其实这里面的差别很大,强烈建议大家所有的全局变量都要初始化,他们的主要差别如下:
编译器在编译的时候针对这两种情况会产生两种符号放在目标文件的符号表中,对于初始化的,叫强符号,未初始化的,叫弱符号。
连接器在连接目标文件的时候,如果遇到两个重名符号,会有以下处理规则:
1、如果有多个重名的强符号,则报错。
2、如果有一个强符号,多个弱符号,则以强符号为准。
3、如果没有强符号,但有多个重名的弱符号,则任选一个弱符号。
基于以上规则看下面的程序:(编译器为gcc 3.4.6, VC下结果不一样)
main.c #include <stdio.h> int x = 1; void foo(void); int main(int argc, char* argv[]) { printf("x1:%d\n", x); foo(); printf("x2:%d\n", x); return 0; } -------- var.c int x = 0; void foo(void) { x = 2; } |
multiple definition of `x'
符合规则1。
把var.c里面的int x = 0;改成 int x; 不做初始化,编译、连接无任何警告,运行结果为:
x:1
x:2
说明连接的时候以main.c中的x为准,foo函数修改的是main.c中定义的x。符合规则2。
把main.c中的初始化也去掉,改成 int x; 编译、连接仍然很顺利,运行结果为:
x:0
x:2
说明main函数和foo函数修改的是同一个x,连接器自己选择了一个x,符合规则3.
大部分情况下,我们不希望连接器为我们做决定,所以我不是很认同后两个规则,至少应该给个警告,而不应该安静地通过。
也许写var.c的人根本不知道main.c里面也有一个x呢,foo函数的本意也许并不是要修改main.c中的x。因为这种问题引起的bug会很难查。
所以我们要尽量把全局变量初始化,对于不想给别的文件引用的变量,也尽量用static修饰。
除了连接时的表现不一样外,未初始化的符号在目标文件的bss段中,而初始化的符号在data段中。
相关文章推荐
- 初始化全局变量实例说明C语言中初始化和未初始化的全局变量所在不同的段
- C语言全局未初始化数据段分析前言:在分析C语言全局未初始化变量时,发现在目标文件中全局未初始化变量
- C语言全局变量的初始化和字符串常量
- C语言 - 变量初始化的重要性
- c语言中全局变量的初始化
- C语言中的全局变量内存分配和初始化顺序
- C语言全局变量初始化、数据类型长度
- C语言全局变量的初始化和字符串常量
- 关于对于c语言全局变量初始化问题
- C语言全局变量的初始化和字符串常量
- C语言中的全局变量内存分配和初始化顺序
- 实例说明C语言中初始化和未初始化的全局变量所在不同的段
- 编译器初始化全局变量,并分配虚拟内存
- c语言学习笔记之全局变量与局部变量
- android studio 将oncreat()中的初始化的变量转化为全局变量的快捷键
- 代码区,初始化全局数据区,BSS,堆区,栈区,程序环境变量区简介
- C语言中全局变量有默认值
- c语言变量的初始化和赋值的区别
- C语言-全局变量与局部变量、全局函数与内部函数
- C语言:全局变量在多个 c 文件中公用的方法