They're different.
const
is just a qualifier, which says that a variable cannot be changed at runtime. But all other features of the variable persist: it has allocated storage, and this storage may be addressed. So code does not just treat it as a literal, but refers to the variable by accessing the specified memory location (except if it is static const
, then it can be optimized away), and loading its value at runtime. And as a const
variable has allocated storage, if you add it to a header and include it in several C sources, you'll get a "multiple symbol definition" linkage error unless you mark it as extern
. And in this case the compiler can't optimize code against its actual value (unless global optimization is on).
#define
simply substitutes a name with its value. Furthermore, a #define
'd constant may be used in the preprocessor: you can use it with #ifdef
to do conditional compilation based on its value, or use the stringizing operator #
to get a string with its value. And as the compiler knows its value at compile time it may optimize code based on that value.
For example:
#define SCALE 1
...
scaled_x = x * SCALE;
When SCALE
is defined as 1
the compiler can eliminate the multiplication as it knows that x * 1 == x
, but if SCALE
is an (extern
) const
, it will need to generate code to fetch the value and perform the multiplication because the value will not be known until the linking stage. (extern
is needed to use the constant from several source files.)
A closer equivalent to using #define
is using enumerations:
enum dummy_enum {
constant_value = 10010
};
But this is restricted to integer values and doesn't have advantages of #define
, so it is not widely used.
const
is useful when you need to import a constant value from some library where it was compiled in. Or if it is used with pointers. Or if it is an array of constant values accessed through a variable index value. Otherwise, const
has no advantages over #define
.