Problem with compiler #if directive

I am facing a strange problem. I cannot find the solution may be one of you can have a clue on what I am doing badly.

Here is a short program to explain the problem :

#include <Arduino.h>

//#define VAR1

#if defined(VAR1)

#warning VAR1 on

void test() {}


#warning VAR1 off


void setup() {}

void loop() {}

#ifdef VAR2

#warning VAR2 on

void testfunction(ABCD testvar){}


#warning VAR2 off


like it is the program compiles and I get the following results:

D:/Documents/PlatformIO/Projects/testcompil/src/main.ino:14:2: warning: #warning VAR1 off [-Wcpp]
D:/Documents/PlatformIO/Projects/testcompil/src/main.ino:26:2: warning: #warning VAR2 off [-Wcpp]

Now if I uncomment the VAR1
it does not compile anymore and I get the following errors :

D:/Documents/PlatformIO/Projects/testcompil/src/main.ino:6:2: warning: #warning VAR1 on [-Wcpp]
#warning VAR1 on
D:/Documents/PlatformIO/Projects/testcompil/src/main.ino:21:2: warning: #warning VAR2 off [-Wcpp]
#warning VAR2 off
D:/Documents/PlatformIO/Projects/testcompil/src/main.ino:10:19: error: variable or field ‘testfunction’ declared void
D:/Documents/PlatformIO/Projects/testcompil/src/main.ino:10:19: error: ‘ABCD’ was not declared in this scope
*** [.pio\build\mhetesp32minikit\src\main.ino.cpp.o] Error 1

VAR2 is not defined but the compiler analysed the content beetween the #ifdef and the #endif

If the file is named .ino the problem occurs
if the file is named .cpp there is no problem

Do you have an explanation for this behavior ?

thanks a lot for your help

Yes, it’s easy. When using .ino format, there is a pre-processing step that automatically extracts all function prototypes in the file, without respecting the macros, and places them on top of the file.

So your function declaration with the unknown ABCD type will be visible and declared at the top of the converted ino -> cpp file.

The absolute same should happen in the Arduino IDE if the pre-processing steps are the same.

Related topics are Build flags unexpected behavior - #2 by maxgerhardt and Tutorial for creating multi cpp file arduino project - #36 by NormanDunbar and ESP32 Arduino: Can someone explain me this behavior - #7 by maxgerhardt.

Please use .cpp files to not have unintended side effects during the .ino -> .cpp conversion. Also, you only get the full intellisense when it’s a .cpp file.

Hi Maxgerhardt,

Thanks for pointing to this weird feature of the pre-processor .
Very strange indeed ! This is a part that should not be compiled but it analyses it…
(what is the reason behind … if a function should not be compiled why to reference it ?)

Knowing that I will code according to it.
Thanks also for the links.

Keep up the good job
Thanks again


I have an other question. Why does it compile when the VAR1 is commented ?
following your explanation the preprocessor should also extract the function listed in the VAR2 section

this should also create an error !!


Because the function declaration is valid on its own when it’s being copied to the top.

No unknown types used in the return value of parameter list.

Not so for the void testfunction(ABCD testvar); prototype since the type ABCD is unknown.

The protype is being declared thanks to the preprocessing to the compiler will check it for correctness, even if no function calls this function or symbol. Every function is compiled per-sé (if it is not optimized away through other optimizations). This “function is not compiled” is actually a removal at the linking stage (link-time-optimization).