Is there const in C?

There are no syntactic differences between C and C++ with regard to const keyword, besides a rather obscure one: in C (since C99) you can declare function parameters as

void foo(int a[const]);

which is equivalent to

void foo(int *const a);

declaration. C++ does not support such syntax.

Semantic differences exist as well. As @Ben Voigt already noted, in C const declarations do not produce constant expressions, i.e. in C you can’t use a const int object in a case label, as a bit-field width or as array size in a non-VLA array declaration (all this is possible in C++). Also, const objects have external linkage by default in C (internal linkage in C++).

There’s at least one more semantic difference, which Ben did not mention. Const-correctness rules of C++ language support the following standard conversion

int **pp = 0;
const int *const *cpp = pp; // OK in C++

int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++

These initializations are illegal in C.

int **pp = 0;
const int *const *cpp = pp; /* ERROR in C */

int ***ppp = 0;
int *const *const *cppp = ppp; /* ERROR in C */

Generally, when dealing with multi-level pointers, C++ says that you can add const-qualification at any depth of indirection, as long as you also add const-qualification all the way to the top level.

In C you can only add const-qualification to the type pointed by the top-level pointer, but no deeper.

int **pp = 0;
int *const *cpp = pp; /* OK in C */

int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */

Another manifestation of the same underlying general principle is the way const-correctness rules work with arrays in C and C++. In C++ you can do

int a[10];
const int (*p)[10] = &a; // OK in C++

Trying to do the same in C will result in an error

int a[10];
const int (*p)[10] = &a; /* ERROR in C */

Leave a Comment