Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

macro definition containing #include directive

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?

like image 497
Bing Jian Avatar asked Nov 05 '08 20:11

Bing Jian


People also ask

What does the macro definition table contains?

Every macro definition consists of a macro definition header statement (MACRO), a macro instruction prototype statement, one or more assembler language statements, and a macro definition trailer statement (MEND), as shown in Figure 1.

How do you define a macro?

A macro is a piece of code in a program that is replaced by the value of the macro. Macro is defined by #define directive. Whenever a macro name is encountered by the compiler, it replaces the name with the definition of the macro. Macro definitions need not be terminated by a semi-colon(;).

What is macro define with example?

Macro is defined as something that covers a large amount, or is large in size. An example of macro is the study of the key driving aspects of an economy; macro economics. An example of macro is a very close up photograph of an ant; a macro photograph.


1 Answers

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 :).

like image 172
Ben Farmer Avatar answered Oct 15 '22 02:10

Ben Farmer