I need to be able to include / exclude certain files at compile time but was seeing strange behavior that I did not understand. I created this sketch that provides three different test cases, none of which behaves as I would expect it to. In the first and third test cases, I expect it to show WED as the output but get MON instead. In the second case, no output is produced. Here is the actual output from this code:
Baseline test: day=4
Simple comparison test:
1==1
Using enum values: MON
Using define values:
Using int values: MON
Is this a compiler problem or am I completely misunderstanding the meaning of #if?
// Multiple experiments with #if and #elif
// 1) Using enum values
enum days {SUN = 1, MON = 2, TUE = 3, WED = 4, THU = 5, FRI = 6, SAT = 7};
// 2) Using #defines
#define Sun 1
#define Mon 2
#define Tue 3
#define Wed 4
#define Thu 5
#define Fri 6
#define Sat 7
// 3) Using integers
int sun = 1;
int mon = 2;
int tue = 3;
int wed = 4;
int thu = 5;
int fri = 6;
int sat = 7;
void setup()
{
Serial.print("Baseline test: ");
int day = WED; // set int to enum valule
Serial.print("day=");
Serial.println(day); // output s/b "day=4"
// Prove that it can do a simple comparison test:
Serial.println("Simple comparison test:");
#if 1 == 2
Serial.println("1==2");
#elif 2 == 3
Serial.println("2==3");
#elif 1 == 1
Serial.println("1==1");
#endif
// Comparison using enum values.
// Expected result is WED
// Actual result is MON
Serial.println();
Serial.print("Using enum values: ");
#if day == MON
Serial.println("MON");
#elif day == TUE
Serial.println("TUE");
#elif day == WED
Serial.println("WED");
#elif day == THU
Serial.println("THU");
#elif day == FRI
Serial.println("FRI");
#elif day == SAT
Serial.println("SAT");
#elif day == SUN
Serial.println("SUN");
#endif
// Comparison using #defines
// Expected result is WED
// Actual result is MON
Serial.println();
Serial.print("Using define values: ");
#if day == Mon
Serial.println("MON");
#elif day == Tue
Serial.println("TUE");
#elif day == Wed
Serial.println("WED");
#elif day == Thu
Serial.println("THU");
#elif day == Fri
Serial.println("FRI");
#elif day == Sat
Serial.println("SAT");
#elif day == Sun
Serial.println("SUN");
#endif
// Comparison using enum values.
// Expected result is WED
// Actual result is MON
Serial.println();
Serial.print("Using int values: ");
#if day == mon
Serial.println("MON");
#elif day == tue
Serial.println("TUE");
#elif day == wed
Serial.println("WED");
#elif day == thu
Serial.println("THU");
#elif day == fri
Serial.println("FRI");
#elif day == sat
Serial.println("SAT");
#elif day == sun
Serial.println("SUN");
#endif
}
void loop(){}
Is this a compiler problem or am I completely misunderstanding the meaning of #if?
If you are expecting the preprocessor to, at compile time, behave the same as the code at run time, then yes, are misunderstanding the preprocessor directives. By the time the code runs, the preprocessor has stripped all the preprocessor directives from the code.
I am not quite that naive. I have been programming for almost 50 years and I do understand the difference between compile and run time issues. What I don't understand is the compiler's behavior in this case. It compares 1 == 1 as the third choice and gets it right. It compares the other values and picks either the first choice or no choice. I don't see the pattern here.
If I #define Wed 3 then I expect the compiler to substitute "Wed" with "3" It doesn't.
What I want is a means to determine which files to include and which to exclude based on options selected by the user in a configuration (.h) file. I am trying to simplify that logic in this test case, but it's not working at all as expected. What code would produce the results I am looking for?
You are trying to use the contents of variables in the preprocessor directives. Why? The preprocessor does not know what value will be assigned to a variable AT RUN TIME.
void setup()
{
Serial.print("Baseline test: ");
Serial.print("day=");
Serial.println(4); // output s/b "day=4"
// Prove that it can do a simple comparison test:
Serial.println("Simple comparison test:");
Serial.println("1==1");
// Comparison using #defines
// Expected result is WED
// Actual result is MON
Serial.println();
Serial.print("Using define values: ");
Serial.println("WED");
}
void loop(){}