1

刚刚抓到了一个愚蠢的错误。我有一个带有CreateFile()函数的 zip 处理库。Winbase.h,包含在我的标题深处的某个地方,重新定义它CreateFileW并且链接器发疯了。

当然,我会winbase在这种特殊情况下排除。它首先不应该在范围内。但是理论上的问题还是很有趣的,

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

4

5 回答 5

5

您可以通过在名称周围加上括号来绕过宏:

(CreateFile)(arguments);

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

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

于 2013-04-26T13:48:42.293 回答
2

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

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

或者在你的情况下

#undef CreateFileW
... // Here the macro is not available
#define CreateFileW CreateFile
于 2013-04-26T06:43:55.013 回答
2

删除有问题的头文件始终是解决此问题的最佳解决方案(尤其是与windows.hor一样大的头文件winbase.h- 它们在许多项目中被包含得太自由了)。

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

当然,另一个重要的事情是“不要使用与 Windows/Linux 系统调用名称匹配的名称”——但是CreateFile对于创建文件的函数来说,这是一个非常明显的名称,因此我可以看到诱惑。

于 2013-04-26T09:08:05.907 回答
1

#undef

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

于 2013-04-26T06:43:20.513 回答
1

除了上述之外,从#undef技术上讲,您对 s 无能为力#define,至少不可移植。

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

对于#define像 WinAPI 标头这样的问题,您应该尽可能地限制它们。不要#define在标题中使用该 API 的 d 类型。您几乎从不想在整个应用程序中使用 API,因此只能在 API 周围一小层的 cpps 中使用它。以这种方式减少依赖关系不仅仅是对代码的其余部分进行消毒。

于 2013-04-26T06:59:12.330 回答