Why is this incorrect? The problem is when assigning b = p
I get the following warning: assignment discards 'const' qualifiers from pointer target type
.
int a = 4;
int *b;
const int *p = &a;
b = p;
CodePudding user response:
You have one pointer which is defined to point to an int
which you allow to be changed, b
; but you do not init it at first.
Then you introduce a pointer to an int
which you do not allow to be changed.
And you point it to an existing int
. I.e. "Look at that int, but don't you change it."
Then you try to assign the "don't touch this" pointer value to the "hey, have an int, do with what you like" pointer.
The compiler tells you that you are inconsistent there, that you are contradicting yourself and cannot really mean what you write into your code.
That is why it is incorrect. Because you violate the rules which you yourself wrote.
CodePudding user response:
p is a pointer to a constant int and you're assigning it to a pointer to a non-constant int.
CodePudding user response:
p
is defined as a const
pointer to int
, which means it cannot be used to modify the int
it points to. You can initialize it from the address of an int
that can be modified or not. Conversely, b
is a pointer to int
that can be used to modify the int
it points to. It should only be initialized from a pointer to int
with the same ability or the address of an int
that is modifiable. b = p
violates this constraint, hence the warning.
Note that b = &a
is OK as a
is modifiable and p = b
is OK too, only restricting p
from being used to modify a
.
You could attempt to silence the warning by casting p
as (int *)p
but it is not recommended: in this particular instance, p
does point to an int
that can be modified, but bypassing the const validation by the compiler makes the code less readable and more error prone.
Qualifying p
as const int *p
is a promise telling I shall not use p
to modify what it points to. The need to break this promise is an indication that something is not properly structured in the program.
There is no recommended way to silence this warning, but you can simply change the code to initialize b
from &a
this way:
int a = 4;
int *b = &a;
const int *p = b;
With the posted order, you could casually write b = (int *)p;
to try and silence the warning, but a good compiler such as clang with warnings enabled will still rightfully warn you that this cast is fishy...
If you really need to remove the constness and want to silence the warning that still occurs with the obvious b = (int *)p;
, you could write this:
b = (int *)(uintptr_t)(const void *)p; // avoid this!
CodePudding user response:
assignment discards 'const' qualifiers from pointer target type
The above warning clearly indicates that assignment operator(=
) ignores const
. This is because b
is a pointer to non-const
int
, whereas p
is pointer to const int
. You can type-cast p
to (int *)
to remove that warning like:
b = (int *)p;
As some has suggested typecasting is not recommended but can be used to silence the warning. But if you see the disassembly you will found that typecasting doesn't change anything.
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-20], 4
lea rax, [rbp-20]
mov QWORD PTR [rbp-8], rax ;; same with/without typecasting
mov rax, QWORD PTR [rbp-8] ;; same as well
mov QWORD PTR [rbp-16], rax
mov eax, 0
pop rbp
ret