Pointer to array with const qualifier in C & C++
Consider following program:
int main()
{
int array[9];
const int (*p2)[9] = &array;
}
It compiles fine in C++ (See live demo here) but fails in compilation in C. By default GCC gives following warnings. (See live demo here).
prog.c: In function 'main':
prog.c:4:26: warning: initialization from incompatible pointer type [enabled by default]
const int (*p2)[9] = &array;
But If I use -pedantic-errors
option:
gcc -Os -s -Wall -std=c11 -pedantic-errors -o constptr constptr.c
it gives me following compiler error
constptr.c:4:26: error: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]
Why it fails in compilation in C but not in C++? What C & C++ standard says about this?
If I use const qualifier in array declaration statement it compiles fine in C also. So, what is happening here in above program?
GCC-gnu
In GNU C, pointers to arrays with qualifiers work similar to pointers to other qualified types. For example, a value of type
int (*)[5]
can be used to initialize a variable of typeconst int (*)[5]
. These types are incompatible in ISO C because theconst
qualifier is formally attached to the element type of the array and not the array itself.
C standard says that (section: §6.7.3/9):
If the specification of an array type includes any type qualifiers, the element type is so- qualified, not the array type.[...]
Now look at the C++ standard (section § 3.9.3/5):
[...] Cv-qualifiers applied to an array type attach to the underlying element type, so the notation “
cv T
,” whereT
is an array type, refers to an array whose elements are so-qualified. An array type whose elements are cv-qualified is also considered to have the same cv-qualifications as its elements. [ Example:typedef char CA[5]; typedef const char CC; CC arr1[5] = { 0 }; const CA arr2 = { 0 };
The type of both
arr1
andarr2
is “array of 5 const char,” and the array type is considered to be const- qualified. —endexample]
Therefore, the initialization
const int (*p2)[9] = &array;
is assignment of type pointer to array[9] of int
to pointer to array[9] of const int
. This is not similar to assigning int *
to a const int *
where const
is applied directly to the object type the pointer points to. This is not the case with const int(*)[9]
where, in C, const
is applied to the elements of the array object instead of the object the pointer points to. This makes the above initialization incompatible.
This rule is changed in C++. As const
is applied to array object itself, the assignment is between same types pointer to const array[9] of int
instead of type pointer to array[9] of int
and pointer to array[9] of const int
.