Search code examples
c++cconstantslanguage-comparisons

Is there const in C?


This question may be naive, but:

  • is there const keyword in C?
  • since which version?
  • are there any semantic and/or syntactic differences between const in C and C++?

Solution

  • 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 */