Strange behavior with Arduino preprocessor
While working on a complicated and awesome sketch for the Video Game Shield, we’ve run into what looks like a minor bug in the Arduino software. It seems like the pre-preprocessor is a bit greedy, and will include libraries even if their #include statement is protected by an #ifdef #endif preprocessor block.
Here’s a quick example sketch to demonstrate the seemingly-incorrect behavior. I tested this with Arduino-0021 on Ubuntu Linux 10.10. Shift-click on the Verify button, and you can see in the compiler output that both the EEPROM and Servo libraries are getting compiled and included in the project.
#define USE_SERVO #ifdef USE_EEPROM #include <EEPROM.h> #endif #ifdef USE_SERVO #include <Servo.h> #endif void setup(){} void loop(){}
If anyone knows why Arduino is behaving in this way or how to work around it, please leave a comment! Thanks!
Wow.
Has been a few years since I’ve slung serious C code around, but that just seems like a bug.
One of the folks on the Arduino Developers mailing list had this to say:
It’s definitely possible. There are a few quirks in the ways the
preprocessing works. It scans for #include’s to decide which
libraries to link and that scan doesn’t take into account other
pre-processor directives. So, yes, this is a bug, but it’s not a
particularly high priority, because the main Arduino sketch files
(i.e. the ones without extensions) don’t necessarily properly support
every single C/C++ construct.
It is indeed a bug. The annoying but really easy workaround I use is to put this at the beginning of my code, or at least before any other preprocessor directives (the var declaration is the important part, obviously the comment is unnecessary):
// fix Arduino IDE regex issue with detecting first non-preprocessor directive
// (breaks when #ifdef is false and contains non-preprocessor line, see:
// http://code.google.com/p/arduino/issues/detail?id=156)
unsigned char ide_workaround = 0;
Same issue. I’m trying to run slightly older open-source GPS code called GPSNet and am getting nowhere with the code as written. Should run on UNO or MEGA from Mike McCauley’s website (http://www.airspayce.com/mikem/arduino/GPSNet/). Any help?
errors:
MARSGPSnet___UNO_ino:5: error: variable or field ‘transmitFunction’ declared void
MARSGPSnet___UNO_ino:5: error: ‘GPSNet’ was not declared in this scope
MARSGPSnet___UNO_ino:5: error: ‘net’ was not declared in this scope
MARSGPSnet___UNO_ino:5: error: ‘GPSReport’ was not declared in this scope
MARSGPSnet___UNO_ino:5: error: ‘report’ was not declared in this scope
MARSGPSnet___UNO_ino:13: error: variable or field ‘printReport’ declared void
MARSGPSnet___UNO_ino:13: error: ‘GPSReport’ was not declared in this scope
MARSGPSnet___UNO_ino:13: error: ‘report’ was not declared in this scope
MARSGPSnet___UNO_ino:63: error: ‘RF22’ does not name a type
MARSGPSnet___UNO_ino.ino: In function ‘void transmitFunction(GPSNet*, GPSReport*)’:
MARSGPSnet___UNO_ino:77: error: ‘printReport’ was not declared in this scope
MARSGPSnet___UNO_ino:83: error: ‘rf22’ was not declared in this scope
MARSGPSnet___UNO_ino.ino: In function ‘void setRadioChannel(uint8_t)’:
MARSGPSnet___UNO_ino:91: error: ‘rf22’ was not declared in this scope
MARSGPSnet___UNO_ino.ino: In function ‘void setup()’:
MARSGPSnet___UNO_ino:151: error: ‘Serial1’ was not declared in this scope
MARSGPSnet___UNO_ino:154: error: ‘rf22’ was not declared in this scope
MARSGPSnet___UNO_ino.ino: In function ‘void checkForGPSInput()’:
MARSGPSnet___UNO_ino:187: error: ‘Serial1’ was not declared in this scope
MARSGPSnet___UNO_ino:223: error: ‘printReport’ was not declared in this scope
MARSGPSnet___UNO_ino.ino: In function ‘void checkForReceivedMessages()’:
MARSGPSnet___UNO_ino:291: error: ‘rf22’ was not declared in this scope