如何在本地抑制#define?

时间:2013-04-26 06:40:34

标签: c++ c-preprocessor

刚刚发现了一个愚蠢的错误。我有一个带有CreateFile()功能的zip处理库。 Winbase.h,包含在我标题深处的某个地方,将其重新定义为CreateFileW,链接器变得疯狂。

当然,在这种特殊情况下,我会排除winbase。它不应该在第一位的范围内。但理论问题仍然很有趣,

有没有办法在本地压制某些定义?

5 个答案:

答案 0 :(得分:5)

您可以通过在名称旁边添加括号来绕过宏:

(CreateFile)(arguments);

这是有效的,因为宏CreateFile是一个类似函数的宏(即它在括号中有一个参数列表);名称后面的右括号与使用类函数宏的语法不匹配,因此预处理器不会展开它。

当然,“正确”的解决方案是正确命名函数,即create_file<g>

答案 1 :(得分:2)

预处理器宏没有C ++范围的概念。 #define只是文本替换。如果你想拥有一个“本地”#define,你可以这样做:

#define CreateFileW CreateFile
... // here I can use the macro
#undef CreateFileW

或者在你的情况下

#undef CreateFileW
... // Here the macro is not available
#define CreateFileW CreateFile

答案 2 :(得分:2)

删除有问题的头文件始终是最好的解决方案(特别是windows.hwinbase.h这个问题 - 在很多项目中,它们包含得太过自由了。

唯一的其他解决方案是#undef offending_symbol

当然,另一个重要的事情是&#34;不要使用与Windows / Linux系统呼叫名称相匹配的名称&#34; - 但CreateFile是创建文件的函数的一个非常明显的名称,所以我可以看到诱惑。

答案 3 :(得分:1)

#undef

删除了定义(但没有别的)。

答案 4 :(得分:1)

除了前面提到的#undef,从技术上来说,你可以对#define做多少,至少不能轻易做到。

最好的方法是根本不使用#define,或者至少尽可能少地使用#undef。有时您只需要一个宏来生成一些样板代码几次。一旦完成,请务必#define该宏。我能想到的#define唯一的其他有效应用包括条件预处理的保护和标志。

对于#define - 像WinAPI标题一样,你应该尽可能地限制它们。请勿在标头中使用该{{1}} d类型的API。您几乎从不想在整个应用程序中使用API​​,因此只能在API周围的小层的cpp中使用它。通过这种方式减少依赖性不仅可以消除代码的其余部分,还可以提供更多功能。