working with a #define statements

Hi,

I thought that a #define statement was supposed to be global to a whole project, or is this not the case?

Here's what I'm doing to test. Firstly I put this as the very first line in my .ino file....

#define BANANA

Then in the setup phase of the .ino file I add this.....

#ifdef BANANA
  Serial.println("banana");  
#else
  Serial.println("no banana");  
#endif

The sketch compiles and uploads fine, when it runs I see the message 'banana'. all working as expected up to this point.

I then add a very similar statement to one of my functions inside a library of mine...

#ifdef BANANA
  Serial.println("more bananas");  
#else
  Serial.println("no more bananas");  
#endif

note - the library is #include'd in the .ino file after the line '#define BANANA'

This compiles and uploads ok, but now I get the additional printout 'no more bananas'

I thought that a #define statement was valid from that point forward, so putting it right at the top of the .ino file (specifically before the #include of the library that it's used in) would mean it should be visible inside that library. Or have I misunderstood something?

thanks

I think you are running afoul of the Arduino IDE munging your .ino int C++ files. As a test, try putting an 'int test = 0;' as the first line.

KeithRB: I think you are running afoul of the Arduino IDE munging your .ino int C++ files. As a test, try putting an 'int test = 0;' as the first line.

not quite sure what you mean, but I've tried adding the line you suggested and I get exactly the same results.

I've also tried adding the lines to a number of different libraries and sketches - same results each time. I'm using arduino 1.6.5 if that's relevant.

cheers

When you place this inside of loop() what happens?

ifdef BANANA

Serial.println("banana");

else

Serial.println("no banana");

endif

.

LarryD: When you place this inside of loop() what happens?

ifdef BANANA

Serial.println("banana");

else

Serial.println("no banana");

endif

.

I get lots of bananas (as expected). so I guess that means the original #include scopes the whole of the .ino file

And if you comment this? //#define BANANA

You have placed your "more banana" #define in the .cpp and NOT in the .h Only the .h is included when you use a #include the cpp is NOT copied in to the .ino

This is standard C/C++

Mark

LarryD: When you place this inside of loop() what happens?

ifdef BANANA

Serial.println("banana");

else

Serial.println("no banana");

endif

.

I get lots of bananas (as expected). so I guess that means the original #include scopes the whole of the .ino file

Ok, think I’ve cracked it (this might be what holmes4 was talking about – thanks)

This is my pseudo code as it stands….

#define BANANA

#include <Library1.h>
#include <Library2.h>
#include <Library3.h>
#include <Library4.h>
#include <Library5.h>

void setup() 
{
#ifdef BANANA
  Serial.println("banana");  
#else
  Serial.println("no banana");  
#endif
}

void loop() 
{
  // this func contains my test for BANANA
  Library5.func();
}

The test in setup() correctly picks up the BANANA, but the one inside Library5.func() doesn’t.

However, if I move my “#define BANANA” Statement to the first line of Library1.h then it seems BANANA is visible to my .ino file and the code in Library1.cpp and the code in Library5.cpp – which is what I want. But if someone could provide an explanation that would be great too!

The C++ compiler moves program lines around, adds function prototypes, etc. and can cause unexpected behavior like what you are observing.

This seems to be a recently introduced problem. I had a similar problem (enum statements that wouldn't work), which was fixed by using an older version of the IDE.

If your "libraries" are truly libraries (i.e. - they consist of a .h file and a .cpp file), then they get compiled separately from the .ino, so they will never see ANY #defines you put in the .ino. The compiled libraries and compiled .ino file are joined only a link time, LONG after the #defines have been tossed away. If you want both the sketch and one or more libraries to "see" #defines, then those #defines must be defined in a separate .h file that is #included into both the sketch AND the libraries.

Regards, Ray L.

OhMyCod: I thought that a #define statement was supposed to be global to a whole project, or is this not the case?

It's not the case. Google "C preprocessor".

The C++ compiler moves program lines around, adds function prototypes, etc. and can cause unexpected behavior like what you are observing.

This seems to be a recently introduced problem. I had a similar problem (enum statements that wouldn't work), which was fixed by using an older version of the IDE.

Totally wrong! This is standard C/C++ behavior.

  1. include copies the the file "included" into the file in which the #include occurs. Think control-c control-v. It's basically just a copy and paste.

  2. All C/C++ compilers work on 1 C/C++ file at a time

The result is that your #define effectively has global /file scope.

Mark

holmes4: Totally wrong! This is standard C/C++ behavior.

  1. include copies the the file "included" into the file in which the #include occurs. Think control-c control-v. It's basically just a copy and paste.

  2. All C/C++ compilers work on 1 C/C++ file at a time

The result is that your #define effectively has global /file scope.

Mark

Not even global/file scope, as that suggests the #define is "seen" by the entire file. It is not "seen" until AFTER the #define appears in the pre-processed source file. #defines cannot be forward-referenced.

Regards, Ray L.

defines cannot be forward-referenced.

Nor can anything. int's, functions etc.

Mark

PS Ray - which part of my post did you object to? It's both bad form and confusing to copy the whole post!

M

RayLivingston: If your "libraries" are truly libraries (i.e. - they consist of a .h file and a .cpp file), then they get compiled separately from the .ino, so they will never see ANY #defines you put in the .ino.

They are

RayLivingston: If you want both the sketch and one or more libraries to "see" #defines, then those #defines must be defined in a separate .h file that is #included into both the sketch AND the libraries.

I seem to have achieved the same thing with a slightly different method (see my post at 10:45). I have added my #define as the top line of the first #included library (library1.h). The #define seems to be in scope for ALL of the subsequent libraries, and the .ino file itself.

Isn't the best solution just to create a file called 'global.h' for all the #defines that require a global scope and then #include this as the first line in my .ino file?