Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76802
  • 博文数量: 25
  • 博客积分: 692
  • 博客等级: 上士
  • 技术积分: 205
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-29 15:42
文章分类
文章存档

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

    嘛,心血来潮了突然想来总结一下constdefine定义的常量的区别。不解释。

     其实#define定义的都不算常量,其实就是一个字面值。大家都知道预处理器会将宏出现的地方自动替换为宏的定义体,然后再把处理后的源文件交给编译器。因此对于

#define MAX 5

之类的,编译器、调试器都看不到符号MAX,因为预处理器用5MAX替换了。因此int a = MAX;事实上等价于int a = 5;

    那么#defineconst的差异到底在哪里呢:我们且从产生的汇编代码谈起。

考虑代码片段

#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其实就是一个立即数寻址,直接将立即数写入aa是储存器间接寻址)。而将一个const赋给a则会经历2步:以直接寻址方式通过b被分配的内存地址将b的值送入eax,再将其内容送入内存里的局部变量a里。

    不难发现,事实上对const常量的访问和变量是一模一样!那啥?Peter Van Der Linden说得不错,const定义的其实不算常量,不如就叫它ReadOnly Variable。因为它和变量几乎一样,除了它是只读的,存放位置不一样。

在应用中,两者差异:

由上可知,宏比const效率高一点点。。。

define定义的宏不能被调试器识别,直接使用会不起作用提示未声明标识符。而const不仅能观察到值,还能看到他的符号。

宏定义导致的语法错误不能被正确定位,因为编译器看到的是宏替换后的结果。

宏不带类型信息,有时候会发生隐式类型转换,从而导致程序结果出人意料。

阅读(1198) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~