coders. I'm learning C programming language and found out such thing as #define directive that allows us to use symbolic constants (following Brain Kernigan). I know that this directives "insert" literals or expressions right into code. Their purpose, as I understood for now, to get rid of magic numbers in a code. Also I found out that #define directives also can't be accessed out of the scope they were declared. That fact makes their usage is very similar to classic variables. My questions to experienced programmers is "What and when should I use? What pros and cons of each mechanism?". At the first glance, I can use them interchangeably. Thank you.

  • Do you understand that #define is a textual substitution, not a variable? Commented Oct 31, 2022 at 8:11
  • 1
    I tried "C const define preprocessor" at Google, and found a lot of articles, like this one "static const" vs "#define" vs "enum".
    – Doc Brown
    Commented Oct 31, 2022 at 10:06

2 Answers 2


You should never use the preprocessor to define symbolic constants. C has had the const keyword since C90, which does the same thing and makes your intent clearer. It also provides better scoping (preprocessor definitions always have file scope, while normal declarations have the scope you'd expect from their location).

  • 2
    I feel uncomfortable with equating const and define. The const does not create a special kind of variable, it just creates a const-qualified type for a variable. The variable still names an object with an address, and may be initialized at runtime. You can't use variables in some places where the C syntax expects literals. In contrast, C++ constexpr does create true compile-time constants.
    – amon
    Commented Oct 31, 2022 at 8:40
  • If it’s defined in C90, it was already in C89 ;-)
    – Christophe
    Commented Oct 31, 2022 at 18:32

Use "variables" (as const objects) when practical.

Better type control.

Use symbolic constants in select cases.


*scanf() width control

Consider reading into a buffer of some fixed size via *scanf() to form a string. "%s" deserves a width, like "%79s" to prevent buffer overflow. Rather than a magic number in the format, derive the buffer size and width via a #define STRING_LEN_MAX 79.

#define STRINGIFY(x) #x

#define STRING_LEN_MAX 79
char buffer[STRING_LEN_MAX + 1];

if (scanf("%" TOSTRING(STRING_LEN_MAX) "s", buffer) == 1) {

Values meant for macro processing


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.