C 和 C++中全局const变量的区别

为研究在目前的C标准和C++标准中全局const变量的区别,做了以下的测试:

(编译器:gcc-4.7.2 ; 环境:32位Ubuntu)

makefile:

 

makec:
  g++ -x c test1.cpp test2.cpp -o test
  ./test
makecpp:
  g++ -x c++ test1.cpp test2.cpp -o test
  ./test

 

测试0: 

test1.cpp

const int m;
int x;
#define PRINT(X) printf(#X" = %d\n",X)
#include <stdio.h>
int main()
{
PRINT(m);
PRINT(x);
return 0;
}

test2.cpp

const int m = 2;

当运行make makec时编译通过,输出为:

m = 0

x = 0

当运行make makecpp时编译不通过,报错:

test1.cpp:1:11: error: uninitialized const ‘m’ [-fpermissive]

结论:

C中默认const全局变量与其他的普通全局变量都是默认初始化为0。

C++中默认const全局变量是需要在定义的时候初始化的,否则编译不通过。

 

测试1:

test1.cpp

extern const int m;
int x;
#define PRINT(X) printf(#X" = %d\n",X)
#include <stdio.h>
int main()
{
PRINT(m);
PRINT(x);
return 0;
}

test2.cpp

const int m = 2;

 

当运行make makec时编译通过,输出为:

m = 2

x = 0

当运行make makecpp时编译不通过,报错:

test1.cpp:(.text+0xa): undefined reference to `m'

结论:

C中默认const全局变量是外部连接的。

C++中默认const全局变量是内部链接的,即具有文件作用域,文件外不可见。

 

测试2:

test1.cpp

extern const int m;
int x;
#define PRINT(X) printf(#X" = %d\n",X)
#include <stdio.h>
int main()
{
PRINT(m);
PRINT(x);
return 0;
}

test2.cpp

static const int m = 2;

 

当运行make makec时编译不通过,报错:

test1.cpp:(.text+0xa): undefined reference to `m'

当运行make makecpp时编译不通过,报错:

test1.cpp:(.text+0xa): undefined reference to `m'

结论:

C++从C中继承了static说明文件作用域的特性。在这里,static并不决定变量的存储区(全局变量都是存储在全局静态数据区),而是决定了其文件作用域,告知编译器该变量是内部链接的。因为在C++中const默认是内部链接的,所以C++中定义全局const int m = 2就相当于C中定义static const int m = 2

综合结论:

在C中用const说明的全局变量与普通的全局变量,除了前者不能主动改变其值外,编译器对其的处理方法都是一样的,都是存储在静态全局数据区,都是默认外部链接,都是默认初始化其内存块为0。

在C++中用const说明的全局变量与普通的全局变量有很大的不同,除了前者不能改变其值外,const说明的全局变量是默认内部链接的,而且没有默认初始化,要求程序员在定义的同时给出初始化的值。这样的特性其实更加严谨,因为内部链接(相当于C中的static)可以防止重名,而常量的定义同时初始化在逻辑上也更合理。

 

posted @ 2013-04-03 13:10  mzorro  阅读(514)  评论(0编辑  收藏  举报