Related
Is there a way to define a macro that contains a #include
directive in its body?
If I just put
the "#include", it gives the error
C2162: "expected macro formal parameter"
since here I am not using # to concatenate strings.
If I use "\# include", then I receive the following two errors:
error C2017: illegal escape sequence
error C2121: '#' : invalid character : possibly the result of a macro expansion
Any help?
So like the others say, no, you can't have #include statements inside a macro, since the preprocessor only does one pass. However, you can make the preprocessor do basically the same thing with a gnarly trick I found myself using recently.
Realise that preprocessor directives won't do anything inside a macro, however they WILL do something in a file. So, you can stick a block of code you want to mutate into a file, thinking of it like a macro definition (with pieces that can be altered by other macros), and then #include this pseudo-macro file in various places (make sure it has no include guards!). It doesn't behave exactly like a macro would, but it can achieve some pretty macro-like results, since #include basically just dumps the contents of one file into another.
For example, consider including lots of similarly named headers that come in groups. It is tedious to write them all out, or perhaps even they are auto-generated. You can partially automate their inclusion by doing something like this:
Helper macros header:
/* tools.hpp */
#ifndef __TOOLS_HPP__
#def __TOOLS_HPP__
// Macro for adding quotes
#define STRINGIFY(X) STRINGIFY2(X)
#define STRINGIFY2(X) #X
// Macros for concatenating tokens
#define CAT(X,Y) CAT2(X,Y)
#define CAT2(X,Y) X##Y
#define CAT_2 CAT
#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z))
#define CAT_4(A,X,Y,Z) CAT(A,CAT_3(X,Y,Z))
// etc...
#endif
Pseudo-macro file
/* pseudomacro.hpp */
#include "tools.hpp"
// NO INCLUDE GUARD ON PURPOSE
// Note especially FOO, which we can #define before #include-ing this file,
// in order to alter which files it will in turn #include.
// FOO fulfils the role of "parameter" in this pseudo-macro.
#define INCLUDE_FILE(HEAD,TAIL) STRINGIFY( CAT_3(HEAD,FOO,TAIL) )
#include INCLUDE_FILE(head1,tail1.hpp) // expands to #head1FOOtail1.hpp
#include INCLUDE_FILE(head2,tail2.hpp)
#include INCLUDE_FILE(head3,tail3.hpp)
#include INCLUDE_FILE(head4,tail4.hpp)
// etc..
#undef INCLUDE_FILE
Source file
/* mainfile.cpp */
// Here we automate the including of groups of similarly named files
#define FOO _groupA_
#include "pseudomacro.hpp"
// "expands" to:
// #include "head1_groupA_tail1.hpp"
// #include "head2_groupA_tail2.hpp"
// #include "head3_groupA_tail3.hpp"
// #include "head4_groupA_tail4.hpp"
#undef FOO
#define FOO _groupB_
#include "pseudomacro.hpp"
// "expands" to:
// #include "head1_groupB_tail1.hpp"
// #include "head2_groupB_tail2.hpp"
// #include "head3_groupB_tail3.hpp"
// #include "head4_groupB_tail4.hpp"
#undef FOO
#define FOO _groupC_
#include "pseudomacro.hpp"
#undef FOO
// etc.
These includes could even be in the middle of codes blocks you want to repeat (with FOO altered), as the answer by Bing Jian requests: macro definition containing #include directive
I haven't used this trick extensively, but it gets my job done. It can obviously be extended to have as many "parameters" as needed, and you can run whatever preprocessor commands you like in there, plus generate actual code. You just can't use the stuff it creates as the input into another macro, like you can with normal macros, since you can't stick the include inside a macro. But it can go inside another pseudo-macro :).
Others might have some comments on other limitations, and what could go wrong :).
I will not argue the merits for it, but freetype (www.freetype.org) does the following:
#include FT_FREETYPE_H
where they define FT_FREETYPE_H elsewhere
C and C++ languages explicitly prohibit forming preprocessor directives as the result of macro expansion. This means that you can't include a preprocessor directive into a macro replacement list. And if you try to trick the preprocessor by "building" a new preprocessor directive through concatenation (and tricks like that), the behavior is undefined.
I believe the C/C++ preprocessor only does a single pass over the code, so I don't think that would work. You might be able to get a "#include" to be placed in the code by the macro, but the compiler would choke on it, since it doesn't know what to do with that. For what you're trying to do to work the preprocessor would have to do a second pass over the file in order to pick up the #include.
I also wanted to do this, and here's the reason:
Some header files (notably mpi.h in OpenMPI) work differently if you are compiling in C or C++. I'm linking to a C MPI code from my C++ program. To include the header, I do the usual:
extern "C" {
#include "blah.h"
}
But this doesn't work because __cplusplus is still defined even in C linkage. That means mpi.h, which is included by blah.h, starts defining templates and the compiler dies saying you can't use templates with C linkage.
Hence, what I have to do in blah.h is to replace
#include <mpi.h>
with
#ifdef __cplusplus
#undef __cplusplus
#include <mpi.h>
#define __cplusplus
#else
#include <mpi.h>
#endif
Remarkably it's not just mpi.h that does this pathological thing. Hence, I want to define a macro INCLUDE_AS_C which does the above for the specified file. But I guess that doesn't work.
If anyone can figure out another way of accomplishing this, please let me know.
I think you are all right in that this task seems impossible as I also got from
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/03d20d234539a85c#
No, preprocessor directives in C++
(and C) are not reflective.
Pawel Dziepak
Anyway, the reason behind this attempt is that I am trying to make the following
repeatedly used code snippet as a macro:
void foo(AbstractClass object)
{
switch (object.data_type())
{
case AbstractClass::TYPE_UCHAR :
{
typedef unsigned char PixelType;
#include "snippets/foo.cpp"
}
break;
case AbstractClass::TYPE_UINT:
{
typedef unsigned int PixelType;
#include "snippets/foo.cpp"
}
break;
default:
break;
}
}
For another task, I need to have a similar function
void bar(AbstractClass object)
where I will place
#include "snippets/bar.cpp"
and of course it is in "snippets/foo.cpp" and "snippets/bar.cpp" that the task-specific code is written.
I have no idea what you are actually trying to do but it looks like what you might want is a templated function.
That way the PixelType is just a template parameter to the block of code.
Why would the macro need to have an #include? if you're #include'ing whatever file the macro is in, you could just put the #include above the macro with all the rest of the #include statements, and everything should be nice and dandy.
I see no reason to have the macro include anything that couldn't just be included in the file.
Contagious is right -- if you're doing:
myFile.c:
#include "standardAppDefs.h"
#myStandardIncludeMacro
standardAppDefs.h:
#define myStandardIncludeMacro #include <foo.h>
Why not just say:
myFile.c:
#include "standardAppDefs.h"
standardAppDefs.h:
#include <foo.h>
And forget the macros?
I'm currently developing a project which involves 7 files: main.cpp, GpioInterface.h, GpioInterface.cpp, Utility.h and Utility.cpp.
Basically in the main.cpp file I declare the board type using #define BOARD_TYPE WHATEVER and then in GpioInterface.h I define some values if this macro has been defined.
It looks something like this:
main.cpp:
#define __USE_BOARD_ WHATEVER // This should go in an external file in the future
#ifdef __USE_BOARD_
// Define some stuff
#endif
#include "GpioInterface.h"
#include "Utility.h"
// main function here
GpioInterface.h:
#ifndef GPIO_INTERFACE_H
#define GPIO_INTERFACE_H
#include <stdint.h>
#include <stdio.h>
#ifdef __USE_BOARD_
enum GPIO_PIN_MODE {
GPIO_PIN_MODE_OUTPUT = 0x00,
GPIO_PIN_MODE_INPUT = 0x01,
};
enum GPIO_PIN_STATE {
GPIO_PIN_STATE_LOW = 0x00,
GPIO_PIN_STATE_HIGH = 0x01,
};
#endif // __USE_BOARD_
// some other stuff
#endif // GPIO_INTERFACE_H
Utility.cpp:
#include "Utility.h"
#include "GpioInterface.h"
void someFunction() {
GPIO_digitalWrite(2, GPIO_PIN_STATE_HIGH); // Write HIGH in pin 2
}
When compiling, the GpioInterface.h file is giving me the following error 'GPIO_PIN_STATE_HIGH' was not declared in this scope.
Any idea how to make the enums defined in GpioInterface.h visible to Utility.cpp?
Thanks!
main.cpp is compiled correctly due to
#define __USE_BOARD_ WHATEVER // This should go in an external file in the future
at the beginning. In Utility.cpp you don't have that define so include of "GpioInterface.h" doesn't define enums.
Ideally, such definition should be moved to a compile-time option e.g. if you're using gcc, it should look like gcc -D__USE_BOARD_=WHATEVER , See:
https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html
Similar option exists for g++ , and for MSVC(++) also, See:
https://learn.microsoft.com/en-us/cpp/build/reference/d-preprocessor-definitions
The advantages are that these are compile-time configurations for a given platform, no need to change the code for each platform and to figure out (like in your case) where the macros are defined.
Unless your GpioInterface.h file, or one of the files it includes, has a macro definition for __USE_BOARD_ then there won't be one, and the #ifdef __USE_BOARD_ will evaluate to false and the enums won't be defined. When the compiler compiles Utility.cpp it won't have a definition for GPIO_PIN_STATE_HIGH and you'll get an error.
The easiest way would be to simply remove the #ifdef around your enums.
Alternatively you could pass __USE_BOARD_ via compiler argument like amritanshu mentioned in his answer or (preferably) declare it in your build configuration settings (of an IDE for example).
If you don't want/can use any IDE or build tool for some reason i'd recommend creating an additional header for global defines and include it everywhere it is needed. This, however, isn't really clean and i always would prefer using build configurations.
I spent a long time trying to figure out why the following wouldn't compile:
enum IPC_RC {OK, EOF, ERROR, NEW };
The error message said only something to the effect that it wasn't expecting to see an open parenthesis. It wasn't until I tried compiling it on a more modern compiler that I learned:
/usr/include/stdio.h:201:13: note: expanded from macro 'EOF'
#define EOF (-1)
So I've finally been burned by a macro! :)
My code doesn't #include <stdio.h> (I don't include anything with a .h suffix), but clearly something I included resulted in the inclusion of <stdio.h>. Is there any way (namespaces?) to protect myself, without tracing down exactly where it was included?
Namespaces will not be a solution because macros ignore them.
So you have two options:
get rid of those 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
};
I don't know a satisfactory solution to the problem you describe, but I just wanted to share one way to handle the situation. Every now and then you (have to) use some particularly obnoxious header which redefins a good part of the English language. The X11 headers of Python.h come to mind. What I ended up doing - and it worked out very well - is that (usually after I notice the breakage) I wrap the 3rd party header in my own header and deal with the uglyness there.
For instance, in projects which make use of the Ruby interpreter, I usually don't include ruby.h directory but rather include an ourruby.h file 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)
That way, I don't have to take care of remembering the fact that some headers are not exactly namespace clean.
I want to have more control over macros such as assertions (and some logging macros that are not directly under my control). So I decided to do something like this, expecting it to work (in case somebody is wondering, the reason it does not work is that the last undef of MY_ASSERT_COPY invalidates MY_ASSERT right before it).
#ifndef ENABLE_FULL_ERROR_ASSERTS
#define MY_ASSERT_COPY MY_ASSERT
#undef MY_ASSERT
#define MY_ASSERT
#endif
// Code for my current class, which happens to be header only
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#define MY_ASSERT MY_ASSERT_COPY
#undef MY_ASSERT_COPY
#endif
Now I know a few ways around it, one being to define another macro for assertions just for that file, which I can then turn off without affecting assertions in any other part of the program. I initially thought this was a really elegant solution (before I found out it did not compile) that will allow me to use MY_ASSERT everywhere and then simply turn it off for particular files.
Since the above doesn't work, is there a workaround that will allow me to selectively kill the macro without affecting the surrounding code and without defining another substitute macro like #define MY_ASSERT_FOR_VECTORS MY_ASSERT
Some compilers provide #pragma push_macroand #pragma pop_macro to save and restore macro state.
Limited portability though.
This may not work in all situations, but maybe you could simply undef the macros, define them as you wish and then undef them again.
The next time your code uses some of these macros it should #include the header files where they were initially defined so it will define those macros again.
One safe option would be:
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#define MY_ASSERT ....
#endif
// Code for my current class, which happens to be header only
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#include "headers.h" //etc
// line above should redefine the macros
#endif
Is there a way to define a macro that contains a #include
directive in its body?
If I just put
the "#include", it gives the error
C2162: "expected macro formal parameter"
since here I am not using # to concatenate strings.
If I use "\# include", then I receive the following two errors:
error C2017: illegal escape sequence
error C2121: '#' : invalid character : possibly the result of a macro expansion
Any help?
So like the others say, no, you can't have #include statements inside a macro, since the preprocessor only does one pass. However, you can make the preprocessor do basically the same thing with a gnarly trick I found myself using recently.
Realise that preprocessor directives won't do anything inside a macro, however they WILL do something in a file. So, you can stick a block of code you want to mutate into a file, thinking of it like a macro definition (with pieces that can be altered by other macros), and then #include this pseudo-macro file in various places (make sure it has no include guards!). It doesn't behave exactly like a macro would, but it can achieve some pretty macro-like results, since #include basically just dumps the contents of one file into another.
For example, consider including lots of similarly named headers that come in groups. It is tedious to write them all out, or perhaps even they are auto-generated. You can partially automate their inclusion by doing something like this:
Helper macros header:
/* tools.hpp */
#ifndef __TOOLS_HPP__
#def __TOOLS_HPP__
// Macro for adding quotes
#define STRINGIFY(X) STRINGIFY2(X)
#define STRINGIFY2(X) #X
// Macros for concatenating tokens
#define CAT(X,Y) CAT2(X,Y)
#define CAT2(X,Y) X##Y
#define CAT_2 CAT
#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z))
#define CAT_4(A,X,Y,Z) CAT(A,CAT_3(X,Y,Z))
// etc...
#endif
Pseudo-macro file
/* pseudomacro.hpp */
#include "tools.hpp"
// NO INCLUDE GUARD ON PURPOSE
// Note especially FOO, which we can #define before #include-ing this file,
// in order to alter which files it will in turn #include.
// FOO fulfils the role of "parameter" in this pseudo-macro.
#define INCLUDE_FILE(HEAD,TAIL) STRINGIFY( CAT_3(HEAD,FOO,TAIL) )
#include INCLUDE_FILE(head1,tail1.hpp) // expands to #head1FOOtail1.hpp
#include INCLUDE_FILE(head2,tail2.hpp)
#include INCLUDE_FILE(head3,tail3.hpp)
#include INCLUDE_FILE(head4,tail4.hpp)
// etc..
#undef INCLUDE_FILE
Source file
/* mainfile.cpp */
// Here we automate the including of groups of similarly named files
#define FOO _groupA_
#include "pseudomacro.hpp"
// "expands" to:
// #include "head1_groupA_tail1.hpp"
// #include "head2_groupA_tail2.hpp"
// #include "head3_groupA_tail3.hpp"
// #include "head4_groupA_tail4.hpp"
#undef FOO
#define FOO _groupB_
#include "pseudomacro.hpp"
// "expands" to:
// #include "head1_groupB_tail1.hpp"
// #include "head2_groupB_tail2.hpp"
// #include "head3_groupB_tail3.hpp"
// #include "head4_groupB_tail4.hpp"
#undef FOO
#define FOO _groupC_
#include "pseudomacro.hpp"
#undef FOO
// etc.
These includes could even be in the middle of codes blocks you want to repeat (with FOO altered), as the answer by Bing Jian requests: macro definition containing #include directive
I haven't used this trick extensively, but it gets my job done. It can obviously be extended to have as many "parameters" as needed, and you can run whatever preprocessor commands you like in there, plus generate actual code. You just can't use the stuff it creates as the input into another macro, like you can with normal macros, since you can't stick the include inside a macro. But it can go inside another pseudo-macro :).
Others might have some comments on other limitations, and what could go wrong :).
I will not argue the merits for it, but freetype (www.freetype.org) does the following:
#include FT_FREETYPE_H
where they define FT_FREETYPE_H elsewhere
C and C++ languages explicitly prohibit forming preprocessor directives as the result of macro expansion. This means that you can't include a preprocessor directive into a macro replacement list. And if you try to trick the preprocessor by "building" a new preprocessor directive through concatenation (and tricks like that), the behavior is undefined.
I believe the C/C++ preprocessor only does a single pass over the code, so I don't think that would work. You might be able to get a "#include" to be placed in the code by the macro, but the compiler would choke on it, since it doesn't know what to do with that. For what you're trying to do to work the preprocessor would have to do a second pass over the file in order to pick up the #include.
I also wanted to do this, and here's the reason:
Some header files (notably mpi.h in OpenMPI) work differently if you are compiling in C or C++. I'm linking to a C MPI code from my C++ program. To include the header, I do the usual:
extern "C" {
#include "blah.h"
}
But this doesn't work because __cplusplus is still defined even in C linkage. That means mpi.h, which is included by blah.h, starts defining templates and the compiler dies saying you can't use templates with C linkage.
Hence, what I have to do in blah.h is to replace
#include <mpi.h>
with
#ifdef __cplusplus
#undef __cplusplus
#include <mpi.h>
#define __cplusplus
#else
#include <mpi.h>
#endif
Remarkably it's not just mpi.h that does this pathological thing. Hence, I want to define a macro INCLUDE_AS_C which does the above for the specified file. But I guess that doesn't work.
If anyone can figure out another way of accomplishing this, please let me know.
I think you are all right in that this task seems impossible as I also got from
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/03d20d234539a85c#
No, preprocessor directives in C++
(and C) are not reflective.
Pawel Dziepak
Anyway, the reason behind this attempt is that I am trying to make the following
repeatedly used code snippet as a macro:
void foo(AbstractClass object)
{
switch (object.data_type())
{
case AbstractClass::TYPE_UCHAR :
{
typedef unsigned char PixelType;
#include "snippets/foo.cpp"
}
break;
case AbstractClass::TYPE_UINT:
{
typedef unsigned int PixelType;
#include "snippets/foo.cpp"
}
break;
default:
break;
}
}
For another task, I need to have a similar function
void bar(AbstractClass object)
where I will place
#include "snippets/bar.cpp"
and of course it is in "snippets/foo.cpp" and "snippets/bar.cpp" that the task-specific code is written.
I have no idea what you are actually trying to do but it looks like what you might want is a templated function.
That way the PixelType is just a template parameter to the block of code.
Why would the macro need to have an #include? if you're #include'ing whatever file the macro is in, you could just put the #include above the macro with all the rest of the #include statements, and everything should be nice and dandy.
I see no reason to have the macro include anything that couldn't just be included in the file.
Contagious is right -- if you're doing:
myFile.c:
#include "standardAppDefs.h"
#myStandardIncludeMacro
standardAppDefs.h:
#define myStandardIncludeMacro #include <foo.h>
Why not just say:
myFile.c:
#include "standardAppDefs.h"
standardAppDefs.h:
#include <foo.h>
And forget the macros?