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?
The const qualifier explicitly declares a data object as something that cannot be changed. Its value is set at initialization. You cannot use const data objects in expressions requiring a modifiable lvalue. For example, a const data object cannot appear on the lefthand side of an assignment statement. C only.
A pointer to a non-const value can change the value it is pointing to. These can not point to a const value.
The const keyword can be used as a qualifier when declaring objects, types, or member functions. When qualifying an object, using const means that the object cannot be the target of an assignment, and you cannot call any of its non-const member functions.
We use the const qualifier to declare a variable as constant. That means that we cannot change the value once the variable has been initialized. Using const has a very big benefit. For example, if you have a constant value of the value of PI, you wouldn't like any part of the program to modify that value.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With