====== Using C++ "constexpr" to replace #define ====== In C, the only way to define symbolic constants was to use ''#define''---in effect, a parameter-less macro. This is often used to specify the value of a symbolic constant in one place, so it can be used later in one or more other places, to declare the size of an array, e.g. #define kMyArraySize 100 ... double MyArray[kMyArraySize]; C++ introduced the ''const'' keyword, which is a big improvement because it allows you to declare //strongly-typed// symbolic constants, e.g. const int MyArraySize = 100; The expression to the right of the ''='' (assignment operator, used as an initialization operator in this context) in such a ''const'' declaration is computed at compile-time by the C++ compiler, and as a result can be used in an array-size declaration like this: double MyArray[kMyArraySize]; Within a class declaration, it's necessary to declare such compile-time ''const'' objects ''static'', e.g. class MyClass { static const int kArraySize = 100; ... double array[kArraySize]; }; I'm not entirely sure why this is, because if the declared constant is indeed constant, defined at compile time, there would never be a need for it to be treated as an instance member. However, the people who write the compilers make the rules, and this is simply the rule. In my original //VanillaJuceAudioProcessor// class declaration, I used an awkward combination of a ''#define'' for a fixed array size, plus an ''enum'' declaration for a constant used in the constructor, like so: #define kNumberOfPrograms 128 class VanillaJuceAudioProcessor : public AudioProcessor , public ChangeBroadcaster { public: enum { maxNumberOfVoices = 16 }; ... private: SynthParameters programBank[kNumberOfPrograms]; ... }; VanillaJuceAudioProcessor::VanillaJuceAudioProcessor() : currentProgram(0) { ... for (int i = 0; i < maxNumberOfVoices; ++i) synth.addVoice(new SynthVoice()); ... } In the first case I was just using ''#define'' the way I always had in C, and in the second case I was following an example I'd seen somewhere, but the truth was I just hadn't figured out how to do it properly in C++, which is class VanillaJuceAudioProcessor : public AudioProcessor , public ChangeBroadcaster { ... private: static const int kNumberOfPrograms = 128; static const int kNumberOfVoices = 16; ... SynthParameters programBank[kNumberOfPrograms]; ... }; The [[wp>C++11|C++11]] standard introduced a more powerful new keyword ''constexpr'', which can be used to define complex expressions to be evaluated at compile-time, and which is particularly useful with templates. I hunted across the web to find any evidence that ''constexpr'' should be used for ordinary constant-declarations, without success, so I'm not sure I understand Jules's admonishment "NEVER use a #define for a constant!! Use constexpr!". I did find one instance in the JUCE source code, where ''constexpr'' was used in this way, in the file ''juce_android_OpenSL.cpp'': class SLRealtimeThread { public: static constexpr int numBuffers = 4; ... }; Since the class //SLRealtimeThread// is not a template class, I have to assume that ''constexpr'' is trivially equivalent to ''const'' in this case, and that Jules was using "constexpr" somewhat generically as a short form of "''const'' expression''.