c language · medium

C: const vs #define vs enum

C offers three ways to name a constant, each different. #define MAX 100 is preprocessor text substitution done before compilation: untyped, unscoped, invisible to the debugger, but usable anywhere text is, including #if and array sizes — so it can clash or substitute surprisingly, hence the SHOUTED naming convention and the need to parenthesize values/arguments. const int kMax = 100; is a real typed, scoped object the debugger sees (and the C++ idiom), but a key C trap is that a const int is not a constant expression, so int buf[kMax]; is illegal in C89 and becomes a runtime variable-length array in C99 rather than a fixed-size array — const means read-only, not necessarily compile-time-known. An enum constant such as enum { Cap = 100 }; is a genuine integer constant expression that can size arrays, label switch cases, and set bit-field widths, while being typed (int) and scoped. The guidance: use enum for compile-time integer constants in C, #define when you need macros/text or non-integer values, and const for typed read-only data.

🔑 Key line

C constants: #define is untyped/unscoped text substitution; a const int is typed & scoped but NOT a C constant expression (int a[constInt] is a VLA); an enum constant is a true integer constant expression — use enum for int consts, #define for text, const for typed read-only.

The code

#define MAX 100 // preprocessor text substitution (no type)
const int kMax = 100; // a typed, scoped object (C: still not a
// constant expression for array sizes!)
enum {
Cap = 100
}; // a real integer constant expression
int buf1[MAX]; // ok (text -> 100)
int buf2[kMax]; // ERROR in C89; VLA in C99 — NOT a const expr
int buf3[Cap]; // ok: enum is a true integer constant

What this lesson walks through

  1. 01#define is blind text substitution
  2. 02const int is a typed object — but not a C constant expr
  3. 03Gotcha — macros are textual, not typed
  4. 04enum gives true integer constants

#define MAX 100 tells the preprocessor to replace the token MAX with 100 before compilation — it has no type, no scope, and is invisible to the debugger. It works anywhere text works (including array sizes and #if), but it ignores scoping and can cause surprising substitutions, so macros are SHOUTED by convention to flag the risk.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of C: const vs #define vs enum and 100+ animated C++ interview lessons.

← Previous
C: Pointers vs Arrays (Decay)
Next →
C: static, extern & Linkage