2011年(25)
分类: C/C++
2011-02-28 11:05:06
=== 关于define宏常量和const限定符常量的区别 ===
本文转自:http://hi.baidu.com/davidacg/blog/item/14878efa765f3b1a6c22ebf9.html
2010-04-25 01:56
嘛,心血来潮了突然想来总结一下const和define定义的常量的区别。不解释。
其实#define定义的都不算常量,其实就是一个字面值。大家都知道预处理器会将宏出现的地方自动替换为宏的定义体,然后再把处理后的源文件交给编译器。因此对于
#define MAX 5
之类的,编译器、调试器都看不到符号MAX,因为预处理器用5将MAX替换了。因此int a = MAX;事实上等价于int a = 5;
那么#define和const的差异到底在哪里呢:我们且从产生的汇编代码谈起。
考虑代码片段
#define NUM 3
const int b = 3;
a = NUM;
a = b;
那么预处理器将宏原地展开后,编译器看到的将是:
const int b = 3;
a = 3;
a = b;
在GCC 4.41下产生的GAS代码为:
80483ba: c7 45 fc 13 00 00 00 movl $0x3,-0x4(%ebp)
80483c1: a1 90 84 04 08 mov 0x8048490,%eax
80483c6: 89 45 fc mov %eax,-0x4(%ebp)
第一行完成了a =3;这句,后两行完成了a=b;这句。可以看到,将一个字面值赋给a其实就是一个立即数寻址,直接将立即数写入a(a是储存器间接寻址)。而将一个const赋给a则会经历2步:以直接寻址方式通过b被分配的内存地址将b的值送入eax,再将其内容送入内存里的局部变量a里。
不难发现,事实上对const常量的访问和变量是一模一样!那啥?Peter Van Der Linden说得不错,const定义的其实不算常量,不如就叫它ReadOnly Variable。因为它和变量几乎一样,除了它是只读的,存放位置不一样。
在应用中,两者差异:
由上可知,宏比const效率高一点点。。。
define定义的宏不能被调试器识别,直接使用会不起作用提示未声明标识符。而const不仅能观察到值,还能看到他的符号。
宏定义导致的语法错误不能被正确定位,因为编译器看到的是宏替换后的结果。
宏不带类型信息,有时候会发生隐式类型转换,从而导致程序结果出人意料。