0

I'm currently developing a project which involves 7 files: main.cpp, GpioInterface.h, GpioInterface.cpp, Utility.h and Utility.cpp.

Basically in the main.cpp file I declare the board type using #define BOARD_TYPE WHATEVER and then in GpioInterface.h I define some values if this macro has been defined.

It looks something like this:

main.cpp:

#define __USE_BOARD_ WHATEVER // This should go in an external file in the future
#ifdef __USE_BOARD_
    // Define some stuff
#endif

#include "GpioInterface.h"
#include "Utility.h"

// main function here

GpioInterface.h:

#ifndef GPIO_INTERFACE_H
#define GPIO_INTERFACE_H

#include <stdint.h>
#include <stdio.h>

#ifdef __USE_BOARD_

enum GPIO_PIN_MODE {
    GPIO_PIN_MODE_OUTPUT = 0x00,
    GPIO_PIN_MODE_INPUT = 0x01,
};

enum GPIO_PIN_STATE {
    GPIO_PIN_STATE_LOW = 0x00,
    GPIO_PIN_STATE_HIGH = 0x01,
};

#endif // __USE_BOARD_
// some other stuff
#endif // GPIO_INTERFACE_H

Utility.cpp:

#include "Utility.h"
#include "GpioInterface.h"

void someFunction() {
    GPIO_digitalWrite(2, GPIO_PIN_STATE_HIGH); // Write HIGH in pin 2
}

When compiling, the GpioInterface.h file is giving me the following error 'GPIO_PIN_STATE_HIGH' was not declared in this scope.

Any idea how to make the enums defined in GpioInterface.h visible to Utility.cpp?

Thanks!

lpares12
  • 3,504
  • 4
  • 24
  • 45
  • 8
    Did you `#define __USE_BOARD` when compiling `Utility.cpp`? BTW you must not use prefixed `_` underscore for any symbols, these are reserved for compiler internals. – user0042 Dec 19 '17 at 10:51
  • @user0042 the problem is that the board I'm currently using is an Arduino-like (in the sense that you use their IDE and then compile and flash with a button) and can't really define any makefile or whatever. This files are all I can modify. And thx for the tip. – lpares12 Dec 19 '17 at 10:58
  • 4
    The way compilation works is that each .cpp file (or .c file in C) is compiled as a separate compilation unit. Before each .cpp file gets compiled, all header files are inserted into one huge temporary file, and this happens every time, for each source file. So, if you are doing this, you will have to make sure `__USE_BOARD_` is defined in every source file which includes the `GpioInterface.h` header. Which indicates that there is a problem with your design. – vgru Dec 19 '17 at 10:59
  • 4
    @lpares12 You need to define the `#define __USE_BOARD_ WHATEVER` in some header file, like for e.g. config.h and make sure this config.h gets included in every source file. – Gaurav Pathak Dec 19 '17 at 11:01
  • Side note: if GpioInterface.h is your header file, then please read https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier and do not use `__USE_BOARD_`. – Werner Henze Dec 19 '17 at 13:01

4 Answers4

2

main.cpp is compiled correctly due to

#define __USE_BOARD_ WHATEVER // This should go in an external file in the future

at the beginning. In Utility.cpp you don't have that define so include of "GpioInterface.h" doesn't define enums.

Karol T.
  • 543
  • 2
  • 13
2

Ideally, such definition should be moved to a compile-time option e.g. if you're using gcc, it should look like gcc -D__USE_BOARD_=WHATEVER , See:

https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html

Similar option exists for g++ , and for MSVC(++) also, See:

https://learn.microsoft.com/en-us/cpp/build/reference/d-preprocessor-definitions

The advantages are that these are compile-time configurations for a given platform, no need to change the code for each platform and to figure out (like in your case) where the macros are defined.

amritanshu
  • 777
  • 13
  • 25
  • 1
    I know, but can't do it since the compilation is done by the company who sells this microcontroller (using a software which I can't modify). The solution I did was to add a "config.h" to all files which needed the flag. – lpares12 Dec 22 '17 at 10:42
  • you can put it in the makefile? – amritanshu Sep 20 '19 at 11:55
1

Unless your GpioInterface.h file, or one of the files it includes, has a macro definition for __USE_BOARD_ then there won't be one, and the #ifdef __USE_BOARD_ will evaluate to false and the enums won't be defined. When the compiler compiles Utility.cpp it won't have a definition for GPIO_PIN_STATE_HIGH and you'll get an error.

Sean
  • 60,939
  • 11
  • 97
  • 136
0

The easiest way would be to simply remove the #ifdef around your enums.

Alternatively you could pass __USE_BOARD_ via compiler argument like amritanshu mentioned in his answer or (preferably) declare it in your build configuration settings (of an IDE for example).

If you don't want/can use any IDE or build tool for some reason i'd recommend creating an additional header for global defines and include it everywhere it is needed. This, however, isn't really clean and i always would prefer using build configurations.

Detonar
  • 1,409
  • 6
  • 18