C++中宏的使用问题详解

2025-05-27 0 32

不遵循C++中关于范围和类型的规则。这经常导致一些微妙的或不那么微妙的问题。因此,C++提供更适合其他的C++(译注:原文为the rest of C++,当指C++除了兼容C 以外的部分)的替代品,例如内联函数、模板与名字空间。

考虑一下:

?

1

2

3

4

5
#include "someheader.h"

struct S {

int alpha;

int beta;

};

如果某人(不明智地)地写了一个叫“alpha”或“beta”的,那么它将不会被编译,或者被错误地编译,产生不可预知的结果。例如,“someheader.h”可能包含:

?

1

2
#define alpha 'a'

#define beta b[2]

(而且仅仅是)全部大写的习惯,会有所帮助,但是对于并没有语言层次上的保护机制。例如,虽然成员的名字包含在结构体的内部,但这无济于事:在编译器能够正确地辨别这一点之前,已经将程序作为一个字符流进行了处理。顺便说一句,这是C 和C++程序开发环境和工具能够被简化的一个主要原因:人与编译器看到的是不同的东西。

不幸的是,你不能假设别的程序员总是能够避免这种你认为“相当白痴”的事情。例如,最近有人报告我,他们遇到了一个包含goto 的。我也见过这种情况,而且听到过一些——在很脆弱的时候——看起来确实有理的意见。例如:

?

1

2

3

4

5

6

7

8

9

10

11

12
#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;

}

作为一个维护的程序员,就会产生这种印象;将“隐藏”到一个头文件中——这并不罕见——使得这种“魔法”更难以被辨别。

一个常见的微妙问题是,一个函数风格的并不遵守函数参数传递的规则。例如:

?

1

2

3

4

5

6

7
#define square(x) (x*x)

void f(double d, int i){

square(d); // 好

square(i++); // 糟糕:这表示 (i++*i++)

square(d+1); //糟糕:这表示(d+1*d+1); 也就是 (d+d+1)

// ...

}

“d+1”的问题,可以通过在“调用”时或定义时添加一对圆括号来解决:

?

1
#define square(x) ((x)*(x)) /*这样更好 */

但是, i++被执行了两次(可能并不是有意要这么做)的问题仍然存在。

是的,我确实知道有些特殊的并不会导致C/C++预处理这样的问题。但是,我无心去发展C++中的。作为替代,我推荐使用C++语言中合适的工具,例如内联函数,模板,构造函数(用来初始化),析构函数(用来清除),异常(用来退出上下文环境),等等。

好了,今天就先到这里,以后我们再来更深入的探讨这个问题

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 C++中宏的使用问题详解 https://www.kuaiidc.com/75208.html

相关文章

发表评论
暂无评论