How to suppress #define locally?

假如想象 提交于 2019-12-11 10:52:38

问题


Just caught a silly bug. I have a zip processing library with a CreateFile() function in it. Winbase.h, included somewhere deep in my headers, redefines it as CreateFileW and linker goes nuts.

Of course I will exclude winbase in this particular case. It just shouldn't be in the scope in the first place. But the theoretical question is still interesting,

Is there a way to suppress some defines locally?


回答1:


Removing the offending header file is ALWAYS the best solution for this (especially one as large as windows.h or winbase.h - they are included far too freely for my taste in many projects).

The only other solution is #undef offending_symbol.

Of course, another important thing is "do not use names that match the Windows/Linux system call names" - but CreateFile is a very obvious name for a function that creates a file, so I can see the temptation.




回答2:


You can get around the macro by putting parentheses around the name:

(CreateFile)(arguments);

This works because the macro CreateFile is a function-like macro (i.e. it takes a list of arguments in parentheses); the right parenthesis after the name doesn't match the syntax for using a function-like macro, so the preprocessor does not expand it.

Of course, the "right" solution is to name the function properly, i.e., create_file. <g>




回答3:


Preprocessor macros have no notion of C++ scope. #defines are just text replacements. If you want to have a 'local' #define, you do something like this:

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

Or in your case

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



回答4:


There is

#undef

which removes defines (but nothing else).




回答5:


Apart from the aforementioned #undef there technically is not much you can do against #defines, at least not portably.

The best way is to not use #define at all, or at least as little as possible and as constrained as possible. Sometimes you just need a macro to generate some boilerplate code a few times. Be sure to #undef that macro once you are done. The only other valid applications of #define I can think of are include guards and flags for conditional preprocessing.

For #define-deseases like the WinAPI headers you just should constrain them as much as possible. Don't use the #defined types of that API in your headers. You almost never want to use an API all over your application, so use it only in the cpps of a small layer around the API. Reducing the dependencies that way gives a lot more than just disinfecting the rest of your code.



来源:https://stackoverflow.com/questions/16230205/how-to-suppress-define-locally

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!