#ifndef running anyway

I have some code I'm working on, and I want to use some defined constants for good practices, but for some reason my defines are being overwritten, and it may be causing issues elsewhere. I have a header file playRecord.h that is being included in my main program. This file has the #ifndef macro in it that seems to run every time. I am using a Raspberry Pi, one with Debian and one with I can't remember what, and KaliLinux. I found the issue on KaliLinux when trying to solve another issue.

My Makefile looks like


CC=g++
CFLAGS=-O2 -lwiringPi -lssd1306 -lnfc -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s

SOURCES := $(wildcard src/*.cpp)
OBJECTS := $(SOURCES:src/%.cpp=obj/%.o)
DEPS := $(wildcard src/*.h)
INCLUDED := $(DEPS:src/%.h=src/%.cpp)

all: bin/heard

bin/heard: 
	$(CC) $(CFLAGS) -g $(INCLUDED) main.cpp -o src/heard


The beginning of the main file looks like
1
2
3
4
5
6
7
8
9
10
#define VOLUME_PLUS 20
#define VOLUME_MINUS 21

#define ACTIVATE 12
#define RECORD 16

#include "volume.h"
//#include "poll.h"	//no use for it yet
#include "display.h"
#include "playRecord.h" 


and the beginning of playRecord.h looks like
1
2
3
4
5
6
7
#ifndef PLAY_RECORD_H
#define PLAY_RECORD_H

#ifndef ACTIVATE
#define ACTIVATE 17	//pin for activation of playing or recording
#define RECORD 27	//pin for selecting recording mode.
#endif 


I can't understand why the pin is still 17 when I defined it as 12 in main.cpp. Is it because of when it's compiled or runtime execution or . . .?
Last edited on
ACTIVATE and RECORD should expand to 12 and 16 respectively for the rest of main.cpp, but if you use these macros in other compilation units they will get defined to 17 and 27 when you include playRecord.h unless you predefine them like you did in main.
Last edited on
That's what I thought, but when I ran them on KaliLinux, ACTIVATE was being set to 17 in playRecord anyway. There wouldn't be a problem with the order it's being compiled in, would there?
Since you #included <playRecord.h> after you defined the values in main.cpp the values in the header file should be the values seen after that inclusion.
I would think that, but when I print the value defined, it's the one in volume.h. Since I compile volume.cpp instead of volume.h (things were not working when I tried using volume.h), would the fact that those same lines are in volume.cpp cause an issue since I include volume.h?
What do you mean by "ACTIVATE was being set to 17 in playRecord anyway"?

Peter87 explained what the problem is. If you include playRecord.h in any file other than main, ACTIVATE will be set to 17 UNLESS you #define ACTIVATE to something else before the include line. It doesn't matter what other files do, or what order you compile them. Defining ACTIVATE to be 12 in main will affect only main.

Note that ACTIVATE is not a global variable; changing it in one compilation unit has no effect on what it is in another compilation unit.
I mean literally what I say. I don't understand why it's being reset, and that's why I'm here. I compile the program and run it, but when I output ACTIVATE, it's 17 not 12.

I #define it in main like you see above, then in every other file that uses the pin (playRecord.h and playRecord.cpp) I #include later, and I use
1
2
3
4
#ifndef ACTIVATE
#define ACTIVATE
#define RECORD
#endif 

in those files like you see above.

When I output the pin later in playRecord.cpp, it is not 12 as I expect it to be, but 17. From what I understand from the above and from classes I've taken and books and webpages I've read. If you #define something before you #include something with #ifndef, then the #ifndef should not be evaluated for that program, but that's not what I'm experiencing. So, I'm asking to see if my assumptions are wrong or if it has something to do with the way I'm compiling the code that is causing this prolem.

From what you're saying, though, it seems I am mistaken, and that when I run the compiler, the volume.cpp and playRecord.cpp don't get the same values in the volume.cpp and playRecord.cpp because the values are not defined according to them? So when the program compiles the values in volume.cpp and playRecord.cpp will take the default values despite main defining them before the inclusion?
Each compilation unit (source file + content of included files) is compiled separately. Before any C++ code can be compiled all preprocessor directives (the ones that start with #) must be taken care of.

The preprocessor directives are very simple and know nothing about the rules of the C++ language itself.

#include is more or less just an automatic copy paste. You would get the exact same result if you copy pasted the content of a header file instead of including it.

When you #define a macro it is only defined in the current compilation unit. When the preprocessor sees the macro name (after it has been defined and outside other preprocessor directives) it simply replaces the macro name with the macro replacement text.

If you define a macro in main.cpp it will not affect other compilation units. If you want a macro to be defined in all compilation units you better put it in a header file that can be included everywhere. Another possibility is to use the compiler to predefine macros globally (with g++ you can do this with the -D flag).
Last edited on
Hey, thanks for that. That makes a lot more sense.
Topic archived. No new replies allowed.