Using C macro variable in #include

80 Views Asked by At

I have C code file containing the following include:

#include MYHEADER

I know such include using variable is a bad practice but it is not my code, I just want to compile it. I want MYHEADER variable to have <some_header.h> value, rather than "some_header.h". I have tried may ways to pass it, so far none of them worked.

E.g. arm-none-eabi-gcc -c -DMYHEADER=<some.h> -o sample.o sample.c does not work, I always get error: #include expects "FILENAME" or \<FILENAME\>. Using ARM GCC compiler on Windows.

Please advise.

2

There are 2 best solutions below

1
Eric Postpischil On BEST ANSWER

The message you get is produced by GCC if MYHEADER is defined to be empty (there are no tokens in its replacement list). If the command-line processor (also called a shell) you are using takes <some.h> to indicate file redirection, with < indicating to take input from some.h and > taking the -o that follows it to indicate writing to -o, then it leaves -DMYHEADER= with an empty replacement list.

If so, a fix may be to quote the switch:

arm-none-eabi-gcc -c "-DMYHEADER=<some.h>" -o sample.o sample.c 

Here are two tests for this, in addition to trying the above command:

  • Check whether your directory contains a file named -o. If so, it was created by the indirection, confirming that is what is happening.

  • Create a file named x.c, put MYHEADER (and nothing else) in it, and execute arm-none-eabi-gcc -E x.c -DMYHEADER=<some.h>. If the command-line processor complains about no file name following >, that confirms the hypothesis. If it executes the command, or if it executes the command after you add, say, foo after the >, the output will reveal what MYHEADER is replaced with. (The -E switch requests preprocessing, so the single line containing MYHEADER will be replaced by a blank line if -DMYHEADER= is passed to GCC.)

One problem with this hypothesis is the command-line processor should have complained it could not open some.h for the input redirection. But perhaps you have a file of that name in your directory, which would satisfy the command-line processor.

Another possibility is that the C standard does not fully specify how tokens resulting from macro replacement in an #include are processed. When <name.h> appears directly in an #include, it is processed by a special grammar token, an h-char-sequence. When macro replacement is used instead, the standard says, in C 2018 6.10.2 4:

… The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.

I do not expect this is the problem, as a test on Compiler Explorer suggests GCC processes a replacement of MYHEADER with <stdio.h> in an ordinary suitable way.

0
Gayatri On

Adding a #define MYHEADER <some_header.h> before the #include MYHEADER might work. or If you have many like this, you could put all the "#define"s in a file.txt and #include that file.txt before using the #inclue MYHEADER