constexpr lets a variable or function participate in compile-time constant evaluation when its requirements are satisfied. Unlike a macro, it keeps the compiler involved, enabling type checking and compile-time evaluation. section 5.2
Replacing an untyped constant macro
A macro such as #define PI 3.1415927 hides the value's type from the compiler. Replacing macro-based constants with modern C++ constant expressions makes type assumptions visible and errors diagnosable during compilation. section 5.2
Listing 5.3 Using macros to define, reduce, and add types
#define PI 3.1415927 #1
#define SQUARE(n) n * n #2
#define FOR(a, b) for (i = a; i < b; ++i); #3
#define FALSE 0 #4
#define TRUE !FALSE
int main() {
int n = 3;
std::cout << SQUARE(n) << '\n';
std::cout << SQUARE(n + (n - 1)) << '\n';
std::cout << SQUARE(++n) << '\n';
int i;
FOR(0, 10)
std::cout << i << '\n';
int truth = FALSE;
++truth; #5
++truth;
if (truth == FALSE)
std::cout << "smooth\n";
else
std::cout << "dismay\n";
return 0;
}
Compare the macro-based constant with the surrounding macro examples to see why untyped substitution can obscure correctness. section 5.2


