I always used #define
to define magic numbers somewhere at the beginning of the the cpp file. I want to change that to const
numbers. (globals declared / defined in the cpp file.) Is this a good idea? Should I put them into anonymous namespace? I never #include
the cpp files anywhere.
-
`constexpr` is better than `#define`, you can place them in unnamed namespace if used at file scope. – Jarod42 Sep 20 '18 at 14:09
-
Firstly, it's preferable to use a named namespace, secondly use constexpr. You could also make them static. – pointerless Sep 20 '18 at 14:09
-
1Do not forget to make them not all uppercase. – Slava Sep 20 '18 at 14:15
-
@Slava What's wrong with uppercase for global / static consts? – Newline Sep 20 '18 at 14:25
-
1@Newline they are uppercase because they are preprocessor macro, not because they are consts. Using compile time constants with uppercase symbols you actually increase risk of the problem and pattern was introduced originaly to avoid name conflict with preprocessor. But bad habits die hard – Slava Sep 20 '18 at 14:30
-
@pointerless They are in a named namespace already but within that I want to put them in anon namespace. Is that OK? You mean static class members or just static globals? Any difference between static constexpr int a = 0; and const int a = 0; if they are global? – Newline Sep 20 '18 at 14:30
-
@Newline `static` for global makes them visible only within compilation unit they are defined. This is old way, modern way is using anonymous namespace. – Slava Sep 20 '18 at 14:31
-
2There's no point making them static or putting them in an anonymous namespace, const variables at namespace scope have internal linkage by default anyway (i.e. the `static` is implied). – Jonathan Wakely Sep 20 '18 at 15:21
-
1@Newline [Stop the constant SHOUTING!](http://accu.org/index.php/articles/1923) – Jonathan Wakely Sep 20 '18 at 15:23
2 Answers
Basically the only reason you have for choosing such #define
"consts" is if the preprocessor itself will need to use them. Other than that, you have a whole heap of advantages for constexpr
over using such #define
s -- they are listed here.
Anonymous namespace are a good solution only if you're going to be using the magic numbers in the same file, as names inside it are never accessible from other translation units because the unnamed namespace has a unique identifier as far as the compiler is concerned. That said, There's no real gain here in putting the magic numbers inside an anonymous namespace, as either const
or constexpr
variables in any namespace scope inherently have internal linkage.
As far as the difference between const
and constexpr
goes in the context of objects, the gist is that while constexpr
denotes a constant value known during compilation, const
only denotes a constant value, that may not be known during compilation.1 This difference is crucial for compile-time programming, or for usage in other constant expressions.
1Do note that a const
integral that is itself being initialized with a constant expression (such as an integer literal) as part of its declaration is implicitly a constant expression even without explicitly declaring it constexpr
:
const int A = 50; // `A` is a constant expression
int n = 50;
const int B = n; // `B` is not a constant expression as it-
// is not being initialized with a constant expression

- 5,600
- 18
- 31
-
-
Note that certain "fastbuild" compilation tools will lump all of your C files together and your anonymous namespace might not be as unique as you'd expect. – Tim Randall Sep 20 '18 at 14:54
-
@TimRandall That's an eye opener friend, can you supply me with some sources so I'll add an appropriate edit? – Geezer Sep 20 '18 at 14:56
-
1@SkepticalEmpiricist I'm afraid I can't at present. I am trying to find anything online to back up my own recollection of this. My inability to do so leaves me doubting my sanity and competence. Please keep your pinch of salt handy. – Tim Randall Sep 20 '18 at 14:59
-
@TimRandall: the *"fastbuild"* is known as [*"Unity build"*](https://stackoverflow.com/questions/543697/include-all-cpp-files-into-a-single-compilation-unit). – Jarod42 Sep 20 '18 at 15:04
-
2
Is this a good idea?
Yes, as #define
has several issue, as for example:
#define SIX 1 + 5
#define NINE 8 + 1
constexpr int the_answer = SIX * NINE; // 42 and not 54
Should I put them into anonymous namespace?
If used at file scope, yes, it makes sense.

- 203,559
- 14
- 181
- 302
-
3
-
_"If used at file scope, yes, it makes sense."_ Why? Your `the_answer` already has internal linkage, so isn't accessible outside the translation unit. What advantage does an anonymous namespace have? – Jonathan Wakely Sep 20 '18 at 15:22
-
@JonathanWakely: OP talked about `const` and not only `constexpr`. but indeed not required. I tend to put all file scope stuff (variables/functions/classes) in unnamed namespace. – Jarod42 Sep 20 '18 at 15:27