Go Down

Topic: working with a #define statements (Read 1 time) previous topic - next topic

OhMyCod

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....
Code: [Select]
#define BANANA

Then in the setup phase of the .ino file I add this.....
Code: [Select]
#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...
Code: [Select]
#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

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.

OhMyCod

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

larryd

#3
Jan 02, 2017, 10:42 pm Last Edit: Jan 02, 2017, 10:43 pm by LarryD
When you place this inside of loop() what happens?

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


.
No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

OhMyCod

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

larryd

And if you comment this?
//#define BANANA
No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

holmes4

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

OhMyCod

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

OhMyCod

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

This is my pseudo code as it stands….

Code: [Select]
#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!

jremington

#9
Jan 03, 2017, 01:29 am Last Edit: Jan 03, 2017, 01:35 am by jremington
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.

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.  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.

PaulMurrayCbr

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".
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

holmes4

Quote
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

RayLivingston

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.

holmes4

#14
Jan 03, 2017, 04:58 am Last Edit: Jan 03, 2017, 05:00 am by holmes4
Quote
#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

Go Up