Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double pointer const-correctness warnings in C

A pointer to non-const data can be implicitly converted to a pointer to const data of the same type:

int       *x = NULL; int const *y = x; 

Adding additional const qualifiers to match the additional indirection should logically work the same way:

int       *      *x = NULL; int       *const *y = x; /* okay */ int const *const *z = y; /* warning */ 

Compiling this with GCC or Clang with the -Wall flag, however, results in the following warning:

test.c:4:23: warning: initializing 'int const *const *' with an expression of type       'int *const *' discards qualifiers in nested pointer types     int const *const *z = y; /* warning */                       ^   ~ 

Why does adding an additional const qualifier "discard qualifiers in nested pointer types"?

like image 708
Michael Koval Avatar asked Feb 20 '11 06:02

Michael Koval


People also ask

What is const correctness in C?

In C, C++, and D, all data types, including those defined by the user, can be declared const , and const-correctness dictates that all variables or objects should be declared as such unless they need to be modified.

What is const pointer in C?

A constant pointer is one that cannot change the address it contains. In other words, we can say that once a constant pointer points to a variable, it cannot point to any other variable. Note: However, these pointers can change the value of the variable they point to but cannot change the address they are holding.

Can pointer change const value?

const int * is a pointer to an integer constant. That means, the integer value that it is pointing at cannot be changed using that pointer.


2 Answers

The reason why const can only be added one level deep is subtle, and is explained by Question 11.10 in the comp.lang.c FAQ.

Briefly, consider this example closely related to yours:

const int i; int *p; int const **z = &p; *z = &i; /* Now p points to i */ 

C avoids this problem by only allowing assignment to discard qualifiers at the first pointed-to level (so the assignment to z here is not allowed).

Your exact example does not suffer from this problem, because the const the second level means that the assignment to *z would not be allowed anyway. C++ would allow it in this exact case, but C's simpler rules do not distinguish between your case and the example above.

like image 81
caf Avatar answered Sep 21 '22 02:09

caf


The FAQ entry linked by the other answer explains why the following code is not permitted:

int **x = whatever; const int **z = x; 

However, your code const int *const *z = x; is quite different, and it does not suffer from the same flaw raised by the FAQ.

In fact, there is conceptually nothing wrong with the latter code. It is just a flaw in the C specification that it is not permitted, and it forces C programmers to include ugly casts in their code.

It would have been possible for C to use the same rules that C++ did; however the C standard committee didn't decide to do that.

like image 25
M.M Avatar answered Sep 18 '22 02:09

M.M