LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1033|回复: 9

参数化的宏,有什么危险? 如:#define SQR(x) ((x) * (x))

[复制链接]
发表于 2007-1-7 22:43:10 | 显示全部楼层 |阅读模式
这是我参照书上抄的,书说有危险,说什么会引起“陷阱”

请高人赐教!
发表于 2007-1-7 23:33:25 | 显示全部楼层
比如你写这个式子:SQR(x++)
你觉得会是多少?
回复 支持 反对

使用道具 举报

发表于 2007-1-8 00:09:05 | 显示全部楼层
x++ 似乎还体现不出问题,++x 貌似可以导致问题
回复 支持 反对

使用道具 举报

发表于 2007-1-8 00:29:09 | 显示全部楼层
((x++)*(x++)) 和 ((++x)*(++x)) 都是是未定义的行为。因为求值顺序不定。
回复 支持 反对

使用道具 举报

发表于 2007-1-8 11:48:31 | 显示全部楼层
这两种情况,在不同的编译器下面会有不同的表现,如果追求速度,那么写程序这样要当心,否则还是写成inline函数为好
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-1-8 12:27:23 | 显示全部楼层
恩,书上就是说写inline 安全,原来“陷阱”就是指这些,呵呵,稍有了解了!
回复 支持 反对

使用道具 举报

发表于 2007-1-8 16:08:47 | 显示全部楼层
Post by zlbruce
((x++)*(x++)) 和 ((++x)*(++x)) 都是是未定义的行为。因为求值顺序不定。

正解! 一般C程序员不会写出这种代码,学生的作业里倒是经常出现。:-)
回复 支持 反对

使用道具 举报

发表于 2007-1-8 21:27:45 | 显示全部楼层
还有像:
  1. #define SQR(x) ((x) * (x))
  2. int fun(int *a)
  3. {
  4. a+=1;
  5. return 1;
  6. }
  7. ....
  8. int i = 1;
  9. SQR(fun(&i));
复制代码

也有危险,因为i被增加了2次的值。调用者可能认为只增加了一次。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-1-9 13:11:57 | 显示全部楼层
Post by kiron
还有像:

  1. #define SQR(x) ((x) * (x))
  2. int fun(int *a)
  3. {
  4. a+=1;
  5. return 1;
  6. }

  7. ....

  8. int i = 1;
  9. SQR(fun(&i));
复制代码


也有危险,因为i被增加了2次的值。调用者可能认为只增加了一次。


版主好像弄错了点,我纠正如下(无聊之举):

#include <iostream>

#define SQR(x) ((x) * (x))

int fun(int *a)
{
        *a += 1;
        std::cout<<*a<<std::endl;
        return(*a);
}

int main()
{
        int i = 2;
        std::cout<<SQR(fun(&i))<<std::endl;
       
        return(0);
}
回复 支持 反对

使用道具 举报

发表于 2007-1-9 22:15:34 | 显示全部楼层
对不起,是错了,改正如下

  1. #define SQR(x) ((x) * (x))
  2. int fun(int *a)
  3. {
  4. *a+=1;
  5. return 1;
  6. }

  7. ....

  8. int i = 1;
  9. SQR(fun(&i));
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表