I want to have a macro defined in a class. I wish to define it first in my main, but use an #ifndef to create it if the user chooses not to. For some reason it would seem like the class is being linked before the main, so my #define in main is not being used. TIA
My main ino
#define TEST_MACRO 4
#include "test.h"
test testclass;
void setup() {
Serial.begin(9600);
testclass.showValue();
}
void loop() {
}
test.h
#ifndef TEST_MACRO
#define TEST_MACRO 5
#endif
#include "Arduino.h"
class test
{
public:
test();
void showValue();
private:
uint16_t testval = TEST_MACRO;
};
test.cpp
#include "test.h"
test::test()
{
;
}
void test::showValue()
{
Serial.println(testval);
}
Expected Result "4" Result "5"
However, if I do this with a test.h file include and no class, it all works as expected.
The problem here is that your use of macros means that you have two different versions of the test
class. Macros are resolved early on in the compilation process, so this means that in main you have this class
class test
{
...
uint16_t testval = 4;
...
};
but in test.cpp you have this class
class test
{
...
uint16_t testval = 5;
...
};
The problem here is that C++ does not allow you to have different definitions of a class. Classes included in header files get defined multiple times, but all the definitions must be identical. This is part of what is called the one definition rule (ODR).
Programs that violate ODR have undefined behaviour and furthermore compilers are not required to diagnose the violation, so you cannot expect to see any compiler or run time error message. Instead you just get unpredictable behaviour from your code.
It's not clear to me what real world problem you are trying to solve using this approach, but it cannot work due to the ODR violation. Perhaps you should explain what you are actually trying to achieve, and ask for suggestions on how to do that. Maybe a template class would fulfil your needs?