Description
TL;DR simplification of a more complicated real example - It appears as if the IDE compile-time code that processes the sketch to handle automatic function declarations injects the results blindly after the last #include, even if there are conditional compilation directives in use:
// #define HASLCD
#include <Wire.h>
#ifdef HASLCD
#include <LiquidTWI.h>
#endif
// int x; // to work around the problem, intersperse some non-#include/non-#define solids to chew on,
// int foo(void); // or avoid the need for any automagic pre-declarition stuff by explicitly predeclaring the function(s)...
#ifdef HASLCD
// The compile problem happens here, because the automagically created pre-declarations are injected
// inside this #ifdef - which in this scenario will be eliminated...
LiquidTWI lcd(0); // Set the LCD I2C address
#endif
void setup() {
#ifdef HASLCD
lcd.begin(20,4); // initialize the lcd
lcd.setBacklight(HIGH);
lcd.home();
lcd.print(ME);
#endif
Wire.begin();
}
void loop() {
int x = foo();
}
// defined after use with no explicit declaration, relies on IDE automagic for pre-declaration...
int foo(void) {
return 1;
}
becomes (in /var/folders/nw/..../sketch.cpp)
#line 1 "include_define_error.ino"
#include <Wire.h>
#ifdef HASLCD
#include <LiquidTWI.h>
#endif
#ifdef HASLCD
#include "Arduino.h"
void setup();
void loop();
int foo(void);
#line 14
LiquidTWI lcd(0);
#endif
and results in (as expected...) compile failures because any of the functions defined after loop() have no associated declarations in scope:
include_define_error.ino: In function 'void loop()':
include_define_error.ino:36:17: error: 'foo' was not declared in this scope
Error compiling.
Obviously, pre-declaring the functions explicitly, or ordering the definitions and uses in such a way as to avoid the need for explicit forward declarations is the "proper" way to solve the problem - but that begs the question of the value of automagically computing declarations... In the spirit of making the automagic work, I moved the conditional variable declaration AFTER some other variable declaration/definition, which seems to patch things back up...
Yeah, I know the IDE handles conditionals poorly, but this type of silent failure is effectively impossible for the most users to debug...