1

I've an header file with all const values I need within the DLL I'm making, such as:

// myHelpers.hpp
const int kMaxNumVoices = 16;
const int kMaxBeats = 32;
....

and so on. Once I include the .hpp on every .cpp, I can use those constant also on std::array definition.

The problem (theoretically) is that this will violate ODR, since a copy of each var will be used (even if they are const) on each compilation unit, right?

Is this acceptable? Or could deal in some undefined behavior? If its not acceptable, whats the right approch to it?

lubgr
  • 37,368
  • 3
  • 66
  • 117
markzzz
  • 47,390
  • 120
  • 299
  • 507

2 Answers2

1

Especially when you intend to use these constants as non-type template parameters (as in std::array), the best approach is to qualify them as constexpr.

constexpr int kMaxNumVoices = 16;
constexpr int kMaxBeats = 32;

However, in order to not violate ODR, you must not ODR-use it (e.g. take the address of it, see this thread for more info). That's basically the same restriction that applies to const-qualified variables.

Once you can migrate your codebase to C++17, additionally mark them inline:

constexpr inline int kMaxNumVoices = 16;
constexpr inline int kMaxBeats = 32;
lubgr
  • 37,368
  • 3
  • 66
  • 117
0

I think these constants like log2 should always be defined by a literal...

but anyway, you can use inline variable after C++17, and if in C++11, you can use unnamed namespace:

namespace{
    int const kMaxNumVoices = 16;
}

it implies these constants are inline.

but an inline variable is only for each individual translation unit, so don't try to modify them and let codes in other translation units to observe it.

RedFog
  • 1,005
  • 4
  • 10