Declaring a const says, "The value of this variable should not change."
Declaring a pointer to a const says, "I have no intention of changing the variable I am pointing to".
Question 1: why do you get an error when a pointer to a variable is assigned the address of a const?
// Example 1
const int i = 0;
int * p = &i; /* Error */
Answer: Because the first line says, "please guarantee that the value of i
doesn't change", but in the second line the compiler can no longer make that guarantee - the type information on the pointer p
is not strict enough to tell the compiler not to allow changes to the pointed-to value i
.
Question 2: why don't you get an error when a pointer to a const is assigned the address of a variable?
// Example 2
int j = 0;
const int * q = &j; /* No error */
Answer: Because a pointer to a const says, "please guarantee that the value of j
does not change via q
". Note that the via q
is important because the pointer to const declaration doesn't mean that the value pointed to must be a constant, only that whoever is using the pointer can't use the pointer to change the value.
A conversion from e.g. char *
to const char *
is always safe. Through the const char *
, the data that's pointed to can't be modified, and that's it.
On the other hand, a conversion from char **
to const char **
can be unsafe, therefore it isn't allowed implicitly. Instead of explaining it, consider the following code:
void foo(const char **bar)
{
const char *str = "test string";
*bar = str; // perfectly legal
}
int main(void)
{
char *teststr[] = {0};
foo((const char **)teststr);
// now teststr points to a `const char *`!
*teststr[0] = 'x'; // <- attempt to modify read-only memory
// ok in this line, there's no const qualifier on teststr!
}
If the conversion from char **
to const char **
when calling foo()
would be implicit, you would have an implicit way of converting a const
away.
Best Answer
Yes.
It invokes undefined behavior, as it tries to change the const pointer.
Recall that
D* const p
declares a variablep
which is aconst
pointer to non-constD
.