pre-processor directive screwiness or just me

I’ve got an Arduino application with a dozen tabs/sketches and one of them is a serial driven LCD sketch. I picked up a parallel LCD and got the LCD4Bit library working so now I want to include both sketches in my project but only use one at any given time.

This sounds like a piece of cake only I’m already in the 14k range for the compile size with just one LCD driver installed. What I found was if I put one definition in my main header file( myDefinitions.h) like this:
#define USE_4BIT_LCD

and then wrap the entire 4bit LCD sketch with this:
#ifdef USE_4BIT_LCD
#include <LCD4Bit.h>
---- entire sketch code in here-----
#endif

And for the serial LCD module I do this:
#ifdef USE_SERIAL_LCD
#include <SoftwareSerial.h>
---- entire sketch code in here-----
#endif

The “#include” directives and code still gets included in the entire project from both sketches and this gets me a “sketch too big” error when compiling.

I then tried a trick which allows me to define the name of the include file in a macro and so I tried defining the correct library headerfile name when required or use the name of my already included “myDefinitions.h” file. It would look like this:
#ifdef USE_4BIT_LCD
#define INCLUDE_THIS <LCD4Bit.h>
else
#define INCLUDE_THIS “myDefinitions.h”
#endif

#ifdef USE_4BIT_LCD

#include INCLUDE_THIS
---- entire sketch code in here-----
#endif

But the compiler says that it can not find LCD4Bit.h

Anybody have any ideas if this is a bug in my head, a bug in the Arduino IDE, or a bug in the gnu compiler?

Thanks.

It's a bug in the IDE, or a limitation in its functionality. The actual #include directive will be properly executed or not by the compiler. The IDE, however, decides which libraries to link against by scanning your sketch for #include's. The code that does this should ignore commented out #include directives, but doesn't attempt to process #ifdef's.

Ok, I'll head over to the Processing group and bring this up if it's not been already. I'll also look at the code handling this and see about adding an ifdef filter for #include inclusions.

It's in the Arduino code-base, so yours truly deserves all the blame. :)

Help is always welcome, of course. Check out: http://svn.berlios.de/wsvn/arduino/trunk/app/preproc/

thanks, I'll look into it.

Hi mellis. I ran into this same issue in continuing my troubleshooting of includes, ifdefs, and codesize.

I confirm that in Arduino 0012 that #includes inside of #ifdef’s are included even when the conditional fails. For example:

//#define DEBUG 1
#ifdef DEBUG
#include <Client.h>
#include <Ethernet.h>
#include <Print.h>
#include <Server.h>
#endif

void setup()
{
int i;
}

void loop()
{
int x = 37;
}

The above has a sketch size of 7770. Which is undesired.

Instead, 622 is the better sketch size which reflects the preprocessor ignoring everything inside the ifdef clause. The only way I can achieve this is to manually comment out the four includes as below:

//#define DEBUG 1
#ifdef DEBUG
// #include <Client.h>
// #include <Ethernet.h>
// #include <Print.h>
// #include <Server.h>
#endif

void setup()
{
int i;
}

void loop()
{
int x = 37;
}

Hi,
I’ve put together another little sketch that shows an error which I think is related to #define etc. problems with sketch preprocessor…

//#define DEBUG     // <--- this is the key line

#ifdef DEBUG
int k = 0;
#endif

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("Hallo");
  
  #ifdef DEBUG
  k++;
  Serial.println(k);
  #endif
  
  delay(2000);
}

When I try to compile it I get this error:

 In function 'void setup()':
error: 'Serial' was not declared in this scope In function 'void loop()':

If I remove the comment in the first line instead, all works fine.

While experimenting a bit on this issue, I’ve also found out that the #define directives in the sketch don’t get passed over to .h and .cpp library files…

Ooops... this thread is more than 1 year old!

I'm using arduino 0018.

So it seems some problems with #include still exist...

I am having the same issues with arduino 0021, anybody knows if it can be fixed? Any workarounds?

I am having the same issues with arduino 0021

There are several issues being discussed here. Are you having all of them? Got some code we can look at?

We currently have the same issue:

// We use ShiftRegLCD (3 wire)
//#define SRLCD

[...]

#ifdef SRLCD
  #include <ShiftRegLCD.h>
  //             (Datapin, Clockpin, Enablepin or TWO_WIRE [, Lines [, Font]]])
  ShiftRegLCD lcd(3, 2, 4, 2); 
#else
  #include <LiquidCrystal.h>
  LiquidCrystal lcd = LiquidCrystal(8, 9, 4, 5, 6, 7); // rs, enable, d4, d5, d6, d7
#endif

[...]

With the second line commented out we get a mass of errors:

LCD_Config_srlcd.cpp: In function 'void setup()':
LCD_Config_srlcd:294: error: 'delay' was not declared in this scope
LCD_Config_srlcd:297: error: 'delay' was not declared in this scope
LCD_Config_srlcd:307: error: 'Serial' was not declared in this scope
LCD_Config_srlcd:308: error: 'serialRead' was not declared in this scope
LCD_Config_srlcd:315: error: 'delay' was not declared in this scope
LCD_Config_srlcd:317: error: 'showStatusLine' was not declared in this scope
LCD_Config_srlcd.cpp: In function 'void loop()':
LCD_Config_srlcd:327: error: 'serialRead' was not declared in this scope
LCD_Config_srlcd:328: error: 'showStatusLine' was not declared in this scope
LCD_Config_srlcd:336: error: 'getKeyPressed' was not declared in this scope
LCD_Config_srlcd:354: error: 'enterPid' was not declared in this scope
LCD_Config_srlcd:359: error: 'enterPid' was not declared in this scope
LCD_Config_srlcd:364: error: 'enterPid' was not declared in this scope
LCD_Config_srlcd:370: error: 'enterRates' was not declared in this scope
LCD_Config_srlcd:375: error: 'enterRates' was not declared in this scope
LCD_Config_srlcd:380: error: 'resetValues' was not declared in this scope
LCD_Config_srlcd:394: error: 'showStatusLine' was not declared in this scope
LCD_Config_srlcd.cpp: In function 'void resetValues()':
LCD_Config_srlcd:418: error: 'serialWrite' was not declared in this scope
LCD_Config_srlcd.cpp: In function 'int showStatusLine()':
LCD_Config_srlcd:451: error: 'format' was not declared in this scope
LCD_Config_srlcd:453: error: 'formatSigned' was not declared in this scope
LCD_Config_srlcd:458: error: 'format' was not declared in this scope
LCD_Config_srlcd:460: error: 'formatSigned' was not declared in this scope
LCD_Config_srlcd:465: error: 'format' was not declared in this scope
LCD_Config_srlcd:467: error: 'formatSigned' was not declared in this scope
LCD_Config_srlcd:473: error: 'format' was not declared in this scope
LCD_Config_srlcd:480: error: 'format' was not declared in this scope
LCD_Config_srlcd:488: error: 'format' was not declared in this scope
LCD_Config_srlcd:495: error: 'format' was not declared in this scope
LCD_Config_srlcd:502: error: 'formatSigned' was not declared in this scope
LCD_Config_srlcd:504: error: 'format' was not declared in this scope
LCD_Config_srlcd:510: error: 'scaleServo' was not declared in this scope

etc. etc.

Arduino 021.

So how can we get a sulution to make our sketch a bit hardware independant? #ifdefs seems not to be the solution.

Best regards,
Carsten

Simple solution: just add the line

void setup();

at the beginning of the sketch (before the first #ifdef macro). The problem is that the Arduino preprocessor tries to insert forward declarations at the beginning of a sketch, which fails if the first statement is in a disabled block of code.