Const correctness in C vs C++ Const correctness in C vs C++ c c

Const correctness in C vs C++


In addition to the differences you cite, and the library differences thatSteve Jessop mentions,

char* p1;char const* const* p2 = &p1;

is legal in C++, but not in C. Historically, this is because Coriginally allowed:

char* p1;char const** p2 = &p1;

Shortly before the standard was adopted, someone realized that thispunched a hole in const safety (since *p2 can now be assigned achar const*, which results in p1 being assigned a char const*); withno real time to analyse the problem in depth, the C committee banned anyadditional const other than top level const. (I.e. &p1 can beassigned to a char ** or a char **const, but not to a char const**nor a char const* const*.) The C++ committee did the furtheranalysis, realized that the problem was only present when a constlevel was followed by a non-const level, and worked out the necessarywording. (See ยง4.4/4 in the standard.)


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++).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 will not work in c.


The reason for some of these differences is to allow us to get rid of preprocessor macros, which was one of Bjarne's early design goals.

In C we might have

 #define MAX_FOOS 10 int foos[MAX_FOOS];

In C++ we'd prefer to be able to write

 const int max_foos = 10; int foos[max_foos];

For that to work max_foos needs to be usable in a constant expression. It also needs to have internal linkage, so the definition can appear in a header without causing multiple definition errors, and more importantly to make it easier for the compiler to not allocate any storage for max_foos.

When the C committee adopted const from C++ they didn't adopt the antipathy to macros, so they didn't need these semantics.