不幸的是,你无法确保其他程序员不犯你所认为的“愚蠢的”错误。比方说,近来有人告诉我,他们遇到一个含“goto”语句的宏。我见到过这样的代码,也听到过这样的论点——有时宏中的“goto”是有用的。例如: 一个常见而微妙的问题是,函数风格的宏不遵守函数参数调用规则。例如: 我知道有些(其它语言中)被称为“宏”的东西并不象C/C++预处理器所处理的“宏”那样缺陷多多、麻烦重重,但我并不想改进C++的宏,而是建议你正确使用C++语言中的其他机制,比如内联函数、模板、构造函数、析构函数、异常处理等。 Q: 宏有什么不好吗?
#include "someheader.h"
struct S {
int alpha;
int beta;
};
如果有人(不明智地)写了一个叫“alpha”或者“beta”的宏,那么这段代码无法通过编译,
甚至可能更糟——编译出一些你未曾预料的结果。比方说:如果“someheader.h”包含了
如下定义: #define alpha 'a'
#define beta b[2]
那么前面的代码就完全背离本意了。
#define prefix get_ready(); int ret__
#define Return(i) ret__=i; do_something(); goto exit
#define suffix exit: cleanup(); return ret__
void f()
{
prefix;
// ...
Return(10);
// ...
Return(x++);
//...
suffix;
}
#define square(x) (x*x)
void f(double d, int i)
{
square(d); // fine
square(i++); // ouch: means (i++*i++)
square(d+1); // ouch: means (d+1*d+1); that is, (d+d+1)
// ...
}
#define square(x) ((x)*(x)) /* better */
正文
[转] 宏有什么不好吗?2007-11-17 18:31:00
【评论】 【打印】 【字体:大 中 小】 本文链接:http://blog.pfan.cn/lym51/31001.html
A: 宏不遵循C++的作用域和类型规则,这会带来许多麻烦。因此,C++提供了能和语言其它部分“合作愉快”的替代机制,比如内联函数、模板、名字空间机制。让我们来看这样的代码:
把宏(而且只有宏)的名称全部用大写字母表示确实有助于缓解问题,但宏是没有语言级保护机制的。例如,在以上例子中alpha和beta在S的作用域中,是S的成员变量,但这对于宏毫无影响。宏的展开是在编译前进行的,展开程序只是把源文件看作字符流而已。这也是C/C++程序设计环境的欠缺之处:程序员和编译器看到的源文件是不同的。
如果你是一个负责维护的程序员,这样的代码被提交到你面前,而宏定义(为了给这个“戏法”增加难度而)被藏到了一个头文件中(这种情况并非罕见),你作何感想?是不是一头雾水?
“d+1”的问题可以通过给宏定义加括号解决:
但是,“i++”被执行两次的问题仍然没有解决。
阅读(2539) | 评论(0)
版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!
评论