A #define is preprocessor text substitution: it's untyped, ignores scope (it leaks from definition to end of translation unit), has no debug symbol, and is prone to the macro hazards from the C preprocessor lesson, precedence bugs without parentheses, and collisions because it ignores namespaces and classes. A constexpr constant (or an enum class for related integer values) is a real, typed, scoped entity: the compiler type-checks it, it respects namespaces and class membership, the debugger can show it by name, and it's guaranteed compile-time so it costs nothing at runtime and can live in flash. You get every benefit a #define constant provided, compile-time value, no runtime cost, with none of the downsides. The only place you still need the preprocessor is genuine compile-time configuration (#ifdef feature flags), not constants.
C++ for Embedded · Interview question
Why prefer constexpr or enum class over #define for constants?
A strong answer
What a weak answer sounds like
You know the answer. Do you know what gets you dinged?
Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.
From the lesson
const Correctness & constexpr
const propagates read-only intent through your whole API; constexpr moves computation to compile time so lookup tables and config land in flash with zero runtime cost.