C Constants
By Flavio Copes
Learn how to work with constants in C using the const keyword or a #define directive, plus the convention of naming constants in uppercase for readability.
In C you have two ways to define a constant: the const keyword, and the #define preprocessor directive. Let’s see both, and when to pick one over the other.
In the last post I introduced variables in C. Constants are values that, once set, cannot change while the program runs. Think of the number of months in a year, or the maximum number of players in a game. Making them constant documents your intent, and lets the compiler stop anyone from changing them by accident.
Using const
A constant is declared similarly to variables, except it is prepended with the const keyword, and you always need to specify a value.
Like this:
const int age = 37;
This is perfectly valid C, although it is common to declare constants uppercase, like this:
const int AGE = 37;
It’s just a convention, but one that can greatly help you while reading or writing a C program as it improves readability. Uppercase name means constant, lowercase name means variable.
A constant name follows the same rules for variable names: it can contain any uppercase or lowercase letter, can contain digits and the underscore character, but it can’t start with a digit. AGE and Age10 are valid names, 1AGE is not.
The compiler enforces the promise. If you later write:
AGE = 38;
the program doesn’t compile. With clang you get error: cannot assign to variable 'AGE' with const-qualified type 'const int'. This is the whole point: a bug that would silently change a value becomes a compile error you fix in seconds.
The fix, when you hit this error on purpose, is to admit the value changes and declare it as a normal variable instead.
Using #define
Another way to define constants is by using this syntax:
#define AGE 37
In this case, you don’t need to add a type, you don’t need the = equal sign, and you omit the semicolon at the end.
The C compiler will infer the type from the value specified, at compile time.
What’s the difference?
#define is handled by the preprocessor, which runs before the compiler. It performs a text substitution: every occurrence of AGE in the code becomes 37 before compilation even starts.
That has consequences. A #define has no type, so the compiler can’t check you’re using it correctly. It also ignores scope: it applies from the point of definition to the end of the file, even inside functions and blocks.
A const instead is a typed value, and it follows the normal scoping rules. Declare it inside a function, and it exists only there.
My advice is to prefer const for typed values in your code, and reserve #define for cases where the preprocessor is what you actually want, like configuration flags.