Using one constant in multiple files

Hi guys!

I just tried to define a constant in a library if it is not defined somewhere else (e. g. in the including sketch). But it seems that both constants are independent of each other. Background: I want to create a library and define constants there but I also want to be able to "override" these constants from the sketch file to prevent changing the library code all the time.

I also tried it with a "global constants file" but this doesn't work neither...

That's my sketch file::

#define MYCONST 234

#include "myconstants.h"
#include <testLib.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while(!Serial)
  delay(2000);
  Serial.println("Serial ready");
  Serial.print("MYCONST INO: ");
  Serial.println(MYCONST);
  c::begin();
}

void loop() {
  // put your main code here, to run repeatedly:

}

That's my testLib.h file:

#ifndef testLib
  #define testLib
  #include <Arduino.h>
  #include "myconstants.h"


  class c {
  public:
    static void begin();
  };
#endif

That's my testLib.cpp file:

#include "testLib.h"

void c::begin(){
  Serial.print("MYCONST H: ");
  Serial.println(MYCONST);
}

And that's my myconstants.h file that's placed in the libraries/testLib/ directory

#ifndef MYCONST
  #define MYCONST 456
#endif

The serial output is

19:53:47.576 -> Serial ready
19:53:47.576 -> MYCONST INO: 234
19:53:47.576 -> MYCONST H: 456

How can I manage to have only one MYCONST in all files (library and sketch)?

Remove

#define MYCONST 234

from your sketch file, I would think. Am I missing your point?

I want exactly the opposite. If MYCONST is defined in the sketch, this definition should be used. Otherwise the definition from the library (=myconstants.h file) should be used.

#ifndef MYCONST
# define MYCONST 234
#endif

if MYCONST is undefined, use the #define above

#if 1
# undef MYCONST 234
# define MYCONST 234
#endif

optionally (#if 1) define MYCONST
undefine MYCONST to avoid any warning and define MYCONST

@gcjr Thanks for your suggestion but I don't understand it, sorry!

Where do I need to write what? Obviously no MYCONST knows about the existence of the other one...

if you add MYCONST and it's defined elsewhere, the compiler generates a warning that MYCONST is redefined.

to avoid the warning/error, add the #undef MYCONST before the #define MYCONST whenever you do add the #define MYCONST. (add both lines, not just one)

Your sketch and the testLib.cpp are two different translation units, they are compiled independently. It is impossible for a constant defined in your sketch to be visible in testLib.cpp.

Macros defined in your sketch before including the header will be visible in the header, but this is bad practice, because it is an ODR violation waiting to happen. Also, don't use macros for constants.

You have two options:

  1. always set the value of the constant in myconstants.h, never in your sketch.
  2. make the “constant” a (static) member variable of your class that you can set from your sketch.

Problem with this is that it is a constant I can't change because it is a const. So, without a changeable constant (at compile time) I can't change an array size (once at compile time)...

Sounds like you need a Template Class.

as already mentioned, a template might be an option.

/*
   template class 
   with a non hardcoded array size
   by noiasca 
 */

template<size_t size>
class Test
{
  public:
    void print()
    {
      for (auto &pin : pins)
        Serial.println(pin);
    }

    Test(byte* pins)
    {
      for (size_t i = 0; i < size; i++)
        this->pins[i] = pins[i];
    }
  private:
    byte pins[size];
};

byte pins[] = {2, 3, 4, 5, 6};
Test<sizeof(pins)> test(pins); 

void setup()
{
  Serial.begin(115200);

  test.print();
}

void loop()
{
}