#define is a preprocessor directive that simply replaces all occurrences of an identifier with a value before compilation. It does not create variables, does not know about types, does not check boundaries, and does not respect scope.
const is a qualifier that creates a real variable, but it is locked for writing after initialization. A const variable has a type, scope, participates in debugging, and can be safer. Such variables are placed in the .rodata segment or on the stack/in memory.
#define — for simple scalar values needed at compile-time, especially if used in preprocessor conditions or array sizes (#define SIZE 16).const — for values that need to be passed in a type-safe way, debugged, and safely exported (in header files, inter-module).const.Example:
#define PI 3.14159 const double G = 9.81; int arr[PI]; // ERROR! PI is not an integer int arr2[G]; // ERROR! G is not a compile-time value
Question: Does const int a = 10; work as a compile-time constant for creating an array: int arr[a];?
Answer: No. In C, const is a qualifier, but the variable is created and initialized at runtime, not at compile-time, so the array size must be a literal or an expression known to the compiler. Use #define, or enum { SIZE = 10 };.
Example of error:
const int a = 5; int arr[a]; // In C89/90 this won't work (VLAs appeared in C99, but not everywhere)
History
In a media server, they attempted to use
const intto set buffer sizes, thinking it was a "compile-time constant". On one compiler (GCC, C99) everything worked, but on most—compilation error (VLA not supported), they urgently rewrote it to #define.
History
In platform-dependent code, they defined a string with
#define NAME "MyApp", used it in several places, and forgot to put it in parentheses. After adding characters to the string without explicit parentheses, they got incorrect results, leading to strange bugs in the logs.
History
In a project with multiple modules, they defined a constant through #define in two places with different values (copy-paste). The result was that the modules worked with different constants, causing data nonconformities, which were only fixed through meticulous debugging.