Let's say I have a magic number
I want to get rid off...
//whatever.cpp
for (int i = 0; i < 42; i++)
{
//...
}
Reasonably I could kill it in two ways:
Either with const int SOMETHING_SOMETHING_MEANING_OF_LIFE = 42
or with constexpr int SOMETHING_SOMETHING_MEANING_OF_LIFE = 42
in the source .cpp
file.
Is there any meaningful difference between the two in this case (I recall the compiler deducing that - in either case - that the value does not change and thus the 42
is actually hardcoded in the resulting loop/unrolled loop/whatever machine-code) or does it come down to personal taste?
In a related issue: what if the magic number
(and thus the thing that replaces it) were declared in a header (.h
) file instead of a source (.ccp
) file - would that change things (and if so, how)?
Is there any meaningful difference between the two in this case (I recall the compilering deducing that - in either case - the value does not change and actually hardcodes the 42 in the resulting loop/unrolled loop/whatever code) or does it come down to personal taste?
There won't be any difference in codegen in the case you have shown.
However, the difference is that a constexpr
variable guarantees that the value is known at compile-time. See VittorioRomeo's answer.
It is also good to write constexpr
if it is truly a compile-time value, for documentation purposes: when someone reads your code and sees constexpr
, they automatically know it is a truly fixed value. This is important in the case the initialization is non-trivial (e.g. a call to a function).
You can also see constexpr
variables as the true replacement for C macros that contained literals (e.g. #define FOO 123
).
Finally, remember that constexpr
implies const
.
In a related issue: what if the magic number (and the thing that replaces it) were declared in a header file instead of a .ccp file - would that change things?
No. However, if you are declaring global variables in a header file, you probably want to use inline
(available in C++17) on top of constexpr
, so that you only have a single entity in the program, which is an advantage to avoid ODR issues and possibly save memory and initialization time.
See Should `const` and `constexpr` variables in headers be `inline` to prevent ODR violations? for more information.