Note that there are some explanatory texts on larger screens.

plurals
  1. POAre #include directives processed prior to macro expansion regardless of their location within a file?
    primarykey
    data
    text
    <p>I came across some code the other day that was similar to the following (the following has been over-simplified for the sake of brevity):</p> <p><strong>config.h</strong></p> <pre><code>#ifndef __CONFIG__ #define __CONFIG__ #define DEVELOPMENT_BLD _TRUE_ #if (DEVELOPMENT_BLD == _TRUE_) #define FILE_EXT ".dev" #else #define FILE_EXT ".bin" #endif #define PROJECT_STRING "my_project" #define FILE_NAME PROJECT_STRING FILE_EXT /* Common include files */ #include "my_defs.h" #endif /* __CONFIG__ */ </code></pre> <p><strong>my_defs.h</strong></p> <pre><code>#ifndef __MY_DEFS__ #define __MY_DEFS__ #define _TRUE_ 1 #endif /* __MY_DEFS__ */ </code></pre> <p>The project had always compiled without any issues, but since I made some minor changes (and the actual project was rather large) I decided to run Lint on it. When I did, I received the following error:</p> <p><code>Warning 553: Undefined preprocessor variable '_TRUE_', assumed 0</code></p> <p>I then wondered why the compiler didn't catch that <code>_TRUE_</code> is defined in my_defs.h which is included <strong>after</strong> the macro's first usage. So I compiled it on a different compiler with the same results - succesful compilation, no warnings and <code>FILE_NAME</code> was correctly evaluated regardless of how I set <code>DEVELOPMENT_BLD</code> (using <code>_TRUE_</code> or <code>!_TRUE_</code>). Here are my two compiler settings:</p> <p><code>ArmCC -c -cpu Cortex-M3 -g -O0 --apcs=interwork -I "..\ARM\CMSIS\Include" -I "..\ARM\INC\NXP\LPC17xx" -o "file.o" --omf_browse "file.crf" --depend "file.d" "file.c"</code></p> <p><code>mingw32-gcc.exe -pedantic -Wall -g -c D:\dev\practice\header_question\main.c -o obj\Debug\main.o</code></p> <p>I decided to run a simple test to see if the value of <code>FILE_NAME</code> was being properly evaluated by the preprocessor. I also wanted to see what the value of <code>DEVELOPMENT_BLD</code> actually was. I ran the following code two times:</p> <p><strong>main.c</strong></p> <pre><code>#include "config.h" #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; int main() { printf("FILE_NAME:%s, WHAT_IS_TRUE:%d", FILE_NAME,DEVELOPMENT_BLD); return 0; } </code></pre> <p>The first time I used the value <code>#define DEVELOPMENT_BLD _TRUE_</code> with this result:</p> <p><code>FILE_NAME:my_project.dev, WHAT_IS_TRUE:1</code></p> <p>The second time I used the value <code>#define DEVELOPMENT_BLD !_TRUE_</code> with this result:</p> <p><code>FILE_NAME:my_project.bin, WHAT_IS_TRUE:0</code></p> <p>My first thought was that perhaps <code>_TRUE_</code> was being defined elsewhere - so just to be sure I commented out <code>#include "my_defs.h"</code>. I then began to receive a compiler error:</p> <p><code>error: '_TRUE_' undeclared (first use in this function)</code></p> <p>All of that leads to my question. Are #include statements required to be evaluated by the preprocessor before macro expansion or did I just get lucky?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload