C Language | Structure Declarations | Type Qualifiers - const

This article introduces the const qualifier for values that must not be changed and the volatile qualifier for values that must not be optimized away.

Read-only Values

A declaration can contain a storage-class specifier, type specifier, type qualifier, declarator, and initializer.

storage-class-specifier type-specifier type-qualifier declarator initializer ...;

The most common type qualifier is const. It marks a value as read-only after initialization.

const int ciValue = n;

Shared values such as an application name or version should be declared once rather than repeated as literals throughout a program. const protects those values from accidental modification.

Code 1

#include <stdio.h>

typedef unsigned char BYTE;
const char APPNAME[] = "Kitty on your lap";
const int VERSION = (15 << 8) | 7;

int main() {
 /* APPNAME[1] = 'X'; */ /* error */
 /* VERSION = 0; */      /* error */
 printf("APPNAME = %s\n" , APPNAME);
 printf("VERSION = %d.%d\n" , (BYTE)VERSION , (BYTE)(VERSION >> 8));
 return 0;
}

When const qualifies an array, every element is read-only.

For pointers, the position of const matters. A pointer to read-only data cannot modify the referenced value, but it can point somewhere else.

const char *str = buf1;
/* *str = 'a'; */ /* error */
str = buf2;       /* OK */

A constant pointer cannot point somewhere else, but it can modify the referenced value.

char *const str = buf1;
*str = 'a';       /* OK */
/* str = buf2; */ /* error */

Code 2

#include <stdio.h>

void Function(const char *str) {
 /* str[0] = 'X'; */ /* error */
 printf("%s\n" , str);
}

int main() {
 Function("Kitty on your lap");
 return 0;
}

Preventing Optimization

The volatile qualifier tells the compiler that a value may change outside the current program, for example through hardware or another privileged process.

volatile int viValue = n;

The compiler must read a volatile value when requested instead of assuming that a previous value remains valid.

Code 3

#include <stdio.h>

volatile int viVariable = 0xFF;
const volatile char *str = "Kitty on your lap";

int main() {
 printf("viVariable = %d\nstr = %s\n" , viVariable , str);
 return 0;
}

const and volatile can be combined. In that case, the current program cannot modify the value, but the value may still change externally.