C Constants

By

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.

Tagged: C · All topics
~~~

Related posts about clang: