5

宏定义污染的解决方法。

 3 years ago
source link: https://blog.csdn.net/yanxiangtianji/article/details/8765986
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
宏定义污染的解决方法。_yanxiangtianji的专栏-CSDN博客
mfc工程调用另一个基本c++工程出错(windows宏定义污染导致<L_TYPE_raw>错误)
include windows.h 后STL的max/min函数会出错(尤其是一些类的成员函数)。

我用基本的C++配合STL写了一个库,编译成静态库lib。

又在同一个工作空间里面建立了个win32 console的工程,调用这个lib,一切正常。
然后我想加个界面,又建立了个基于对话框的mfc工程,用一样的方法include静态库工程的头文件,居然说我原来那个工程的文件语法有错,而且报的很奇怪,例如:
C/C++ code ?
#include ...
class  Operation
{
public :
enum  kind_t{NONE=0,ADD,DELETE,REVERSE};
kind_t kind;
Node::pointer_t from,to;
public :
...
};
它说我enum的那一行在“)”前面缺少“}”。
2>d:\my program\projects\bayesian\bayesian\operation.h(12) : error C2143: 语法错误 : 缺少“}”(在“(”的前面)
2>d:\my program\projects\bayesian\bayesian\operation.h(12) : error C2059: 语法错误 : “<L_TYPE_raw>”
2>d:\my program\projects\bayesian\bayesian\operation.h(12) : error C2143: 语法错误 : 缺少“;”(在“}”的前面)
2>d:\my program\projects\bayesian\bayesian\operation.h(12) : error C2238: 意外的标记位于“;”之前

一开始怀疑是头文件顺序的问题,后来发现不是。

经过反复测试后发现,这其实是windows.h中的宏定义污染导致的。

在windows.h间接导入的WinNT.h中宏定义了“DELETE”为一个整数。

单独编译那个lib工程以及那个使用基本C++的win32 console工程,由于没有导入windows.h,所以编译他们的时候一切正常。但是在MFC工程里面,由于在这个导入是根植于mfc框架中的,无法避免,所以导致了宏定义污染。宏定义在预编译阶段覆盖掉了我的有效标示符,导致莫名其的错误。

相同的问题还出现在STL的max,min一些函数上。

0,适用#undef xxx来取消xxx的宏定义。

此方法过于暴力,只适用简单情况,对于复杂情况,你undef掉的东西在编译其他库文件的时候是必须的,会导致编译错误。

温和方法:

根本思路是让与编译器认为你的标示符是不同于宏定义中标示符的。

1,最基本的方法就是给自己定义的标示符换个名字,加个前缀。

这样最简单有效,但是不适用于STL组件。

2,名字包装,用括号包裹函数名(定义和调用都要)。

原理是让预编译器看到标示符与“(”之间还有一个“)”,破坏了结构。

特点就是简单。这种方法只适用于带参数的宏定义,即基本只能保护函数,无法保护变量(常量)。但它无法保护成员函数。

因为obj.do()如果写成obj.(do)()是不合语法的。

这里这个例子从语义上不太恰当,只用来说明意思。

3,用其他宏间隔开,自己定义一个空的宏。放在函数名与括号之间(和函数名之间要有空格:-))。

这种方法稍微复杂一点。同样只能保护函数,不能保护变量(常量)。但是它可以保护成员函数,和作用域标示符中的函数。

因为在C++中函数名和函数参数列表之间可以有任意多个间隔符。

下面是一个完整的例子:

转载要有素质,这个例子来自:http://blog.chinaunix.net/uid-22283027-id-3393561.html

原载于http://blog.csdn.net/yanxiangtianji

转载请注明出处


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK