So I read the interesting answers about what are the differences between constexpr and const but I was curious about are the differences between #define and constexpr ? I feel like constexpr is just a #define where the type can be chosen.
-
1Having an explicit type is kind of important to help avoid mistakes and the problems those mistakes could lead to. – Some programmer dude Feb 12 '21 at 17:50
-
1I agree, but that's the only difference ? – Antonin GAVREL Feb 12 '21 at 18:00
-
1`#define` directives create macro substitution, while `constexpr` variables are special type of variables. They literally have nothing in common beside the fact that before `constexpr` (or even `const`) variables were available, macros were sometimes used when currently `constexpr` variable can be used. But both have wide area of applications which are not overlapping with each other. – SergeyA Feb 12 '21 at 18:15
2 Answers
You are quite correct.
#define
(also called a 'macro') is simply a text substitution that happens during preprocessor phase, before the actual compiler. And it is obviously not typed.
constexpr
on the other hand, happens during actual parsing. And it is indeed typed.
Comes without saying that, wherever you can, using constexpr
is a bit safer.

- 242
- 1
- 4
-
Just to clarify for myself (and validate my testing in g++). I understand that constexpr compiles differently depending on the type, but if we're talking purely about built-in types, constexpr should result in a zero cost abstraction over #define, right? – David Aug 16 '23 at 19:31
Statements defined using #define
are called macros. And macros are used in a multitude of uses.
- We can use them to conditionally compile sections of code.
#ifdef ONE
int AddOne(int x) { return x + 1; }
#else
int AddTwo(int x) { return x + 2; }
#endif
- When we don't need to store constants in a variable.
#define MAX_BOUND 1000
#define MIN_BOUND 10
- For places where we can use a macros to change the type of data.
#ifdef USE_WIDE_CHAR
#define TEXT(...) L##__VA_ARGS__
#else
#define TEXT(...) __VA_ARGS__
#endif
- To define keywords based on a condition.
#ifdef BUILD_DLL
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
Since they are resolved before the actual compilation phase, we can make small improvement to the source code depending on certain factors (platforms, build systems, architecture, etc...).
constexpr
essentially states that a variable or function can be resolved at compile time, but is not guaranteed.
I feel like constexpr is just a #define where the type can be chosen.
Its not completely true. As I stated before, because they are resolved before the compilation phase, we can take some advantages of it. The only common use would be for constant values which the compiler could easily replace as an optimization. Apart from that, the use cases are different.

- 3,263
- 2
- 6
- 24