C ++ How to protect yourself from stdio.h macros

For a long time I tried to find out why the following will not compile:

enum IPC_RC {OK, EOF, ERROR, NEW }; 

The error message says only that he did not expect to see an open parenthesis. This was only after I tried to build it on a more modern compiler, which I recognized:

 /usr/include/stdio.h:201:13: note: expanded from macro 'EOF' #define EOF (-1) 

So, I finally got burned with a macro! :)

My code is not #include <stdio.h> (I do not include anything with the suffix .h), but obviously something that I included led to the inclusion of <stdio.h> . Is there a way (namespaces?) To protect myself without tracking where exactly it was included?

+6
source share
2 answers

Namespaces will not be a solution because macros ignore them.

So, you have two options:

  • get rid of these macros yourself:

     #ifdef EOF #undef EOF #endif 
  • use a prefix with your enum values:

     enum IPC_RC { IPC_OK, IPC_EOF, IPC_ERROR, IPC_NEW }; 
+3
source

I do not know a satisfactory solution to the problem you are describing, but I just wanted to share one way to deal with the situation. From time to time you (have to) use some particularly unpleasant heading that redefines a significant part of the English language. The X11 Python.h come to mind. What I ended up - and it worked out very well - is that (usually after I noticed a break) I wrapped the third-party header in my own header and figured out the ugliness.

For example, in projects that use the Ruby interpreter, I usually do not include the ruby.h directory, but rather include ourruby.h , which looks something like this:

 #ifndef RUBY_OURRUBY_H #define RUBY_OURRUBY_H // In Ruby 1.9.1, win32.h includes window.h and then redefines some macros // which causes warnings. We don't care about those (we cannot fix them). #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable:4005) #endif #include <ruby.h> #ifdef _MSC_VER # pragma warning(pop) #endif // In Ruby 1.8.7.330, win32.h defines various macros which break other code #ifdef read # undef read #endif #ifdef close # undef close #endif #ifdef unlink # undef unlink #endif // ... #endif // !defined(RUBY_OURRUBY_H) 

Thus, I do not have to worry about remembering that some headers are not an exact namespace.

+1
source

Source: https://habr.com/ru/post/950033/


All Articles