问题
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. #define
s 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 #define
s, 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 #define
d 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