Const correctness in C vs C++

C++CConstants

C++ Problem Overview


I understand what const correctness means and my question is not about what const correctness is. So I am not expecting an explanation or C++-FAQ links for that.

My questions are:

  • What are the semantic differences between const in C and const in C++? and
  • What is the reason for the difference?

Quotes from the respective standards which make the differences clear would be nice to have.

I regularly switch between C and C++ and I would like to know the important points that one should keep in mind while doing so.

I don't seem to remember the reason for these (special thanks if you can provide a reasoning) but from the top of my mind, I can remember:

  • const variables in C++ have internal linkage by default, while in C they have default external linkage;
  • const objects can be used as compile-time values in C++, but cannot be used as compile-time values in C;
  • Pointers to string literals must be an char const* in C++ but in C it can be char*.

What am I missing?

C++ Solutions


Solution 1 - C++

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

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

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

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

Shortly before the standard was adopted, someone realized that this punched a hole in const safety (since *p2 can now be assigned a char const*, which results in p1 being assigned a char const*); with no real time to analyse the problem in depth, the C committee banned any additional const other than top level const. (I.e. &p1 can be assigned to a char ** or a char **const, but not to a char const** nor a char const* const*.) The C++ committee did the further analysis, realized that the problem was only present when a const level was followed by a non-const level, and worked out the necessary wording. (See §4.4/4 in the standard.)

Solution 2 - C++

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.

Solution 3 - 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlok SaveView Question on Stackoverflow
Solution 1 - C++James KanzeView Answer on Stackoverflow
Solution 2 - C++Prasanth MadhavanView Answer on Stackoverflow
Solution 3 - C++Alan StokesView Answer on Stackoverflow