打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C/C 的全局变量初始化与不初始化的区别

C/C++的全局变量初始化与不初始化的区别

本文介绍C/C++的全局变量初始化与不初始化的区别。

  在C语言里,全局变量如果不初始化的话,默认为0,也就是说在全局空间里:

  int x =0; 跟 int x; 的效果看起来是一样的。但其实这里面的差别很大,强烈建议大家所有的全局变量都要初始化,他们的主要差别如下:

  编译器在编译的时候针对这两种情况会产生两种符号放在目标文件的符号表中,对于初始化的,叫强符号,未初始化的,叫弱符号。

  连接器在连接目标文件的时候,如果遇到两个重名符号,会有以下处理规则:

  1、如果有多个重名的强符号,则报错。

  2、如果有一个强符号,多个弱符号,则以强符号为准。

  3、如果没有强符号,但有多个重名的弱符号,则任选一个弱符号。

  基于以上规则看下面的程序:(编译器为gcc 3.4.6, VC下结果不一样)


   main.cpp
  int x;
  void foo();
  int main(int argc, char* argv[])
  {
  printf("x1:%d\n", x);
  foo();
  printf("x2:%d\n", x);
  return 0;
  }
  int x;
  void foo()
  {
  x = 2;
  }

  因为两个文件里面的x都被初始化了,所以编译出来的两个目标文件里x都是强符号,连接的时候会报错:

  multiple definition of `x'

  符合规则1。

  把var.cpp里面的int x = 0;改成 int x; 不做初始化,编译、连接无任何警告,运行结果为:

  x:1

  x:2

  说明连接的时候以main.cpp中的x为准,foo函数修改的是main.cpp中定义的x。符合规则2。

  把main.cpp中的初始化也去掉,改成 int x; 编译、连接仍然很顺利,运行结果为:

  x:1

  x:2

  说明main函数和foo函数修改的是同一个x,连接器自己选择了一个x,符合规则3.

  大部分情况下,我们不希望连接器为我们做决定,所以我不是很认同后两个规则,至少应该给个警告,而不应该安静地通过。

  也许写var.cpp的人根本不知道main.cpp里面也有一个x呢,foo函数的本意也许并不是要修改main.cpp中的x。因为这种问题引起的bug会很难查。

  所以我们要尽量把全局变量初始化,对于不想给别的文件引用的变量,也尽量用static修饰。

  除了连接时的表现不一样外,为初始化的符号在目标文件的bss段中,而初始化的符号在data段中。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
解析出c++中的内部链接与外部链接_学习笔记
extern "C" - C基础 - 石头
C 语言 全局变量多处定义 (强符号与弱符号)
编程语言C语言 全局变量和局部变量区别 - C语言零基础入门教程
extern C
语言全局变量那些事儿
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服