const and Pointers
const
is a keyword widely used in C and C++. Variable modified byconst
cannot be a Lvalue of operator =
, which means it can not be modified after it is initialized.
const
in C and C++
const
in C and C++In C, the variable modified by const
is called a constant variable, which means it is still a variable, not a constant. For example, it is invalid to declared array size with a const int
variable.
Therefore, the only difference with a const
is that it can not be appended to an assignment expression. However, its memory can be modified.
In C++, the variable modified by const
is regarded as a real constant, and has the same nature with a constant, for example can be used to initialize an array. Actually, all occurrences of const
variables are replaced by the initial value of it in the compiling process. So the same code has different result in C++.
Notice that *p does change the memory of a at runtime in this case, but a has been replaced at compile time, so this change has no effect.
If we initialize a const
variable with a normal variable instead of ab immediate value, then the const
variable acts as a constant variable, and no longer has the nature of constants.
const
and Pointers
const
and Pointersconst
keyword ensures two things. The first one, which we have already known, is that a const
variable cannot be a Lvalue, which means it cannot be modified directly. Besides, const
also makes sure that the constant can not be modified indirectly, which means the memory address of a constant can not be exposed to a normal pointer nor reference.
In order to fix this, we should also modified the pointer with const
, telling the compiler that what the pointer points to can not be modified indirectly with dereference as well. But there are various ways in adding const
to a pointer:
Are there any differences? C++ syntax clarifies that const
modifies the nearest type. In the first case, const
works on int, which means that *p, what p points to, can not be changed with dereference. But p itself doesn't have any regulations, and it can be changed. In the second case, const
also modifies int, so it has the same effect as the first one. In the third case, const
modifies int *, which means p can not be changed, but what p points to can be changed by dereference. The last case has both const
on int and int *, which means both p and what p points to can not be changes.
The most common error in using const
is the mismatch in type conversion. Now suppose we have the following code, which of those statements will raise an error?
In the first case, p1 has a type of const int *, and &a has a type of int *, this conversion is valid. We now knows that *p1, which is the content that p1 points to can not be modified, but there's nothing to do with a, because a is not a constant, there is no constraint in changing a's value. Now look at the second case, what is the type of p2, is it int *const ? Notice that if there is no * after const
, then const
should not be included into the type.
In the above code, q1 and q2 both have the type int *. So in the second case, p2 has the type of int *, and &a has the type of int * as well, so it is a valid conversion. In the third case, p3 and p2 both have a type of int *, so this conversion is correct as well. In the last case, p4 has a type of int *, and p1 has a type of const int *, this is invalid! Remember that const
makes sure that the constant can not be modified indirectly, so p4 has to be const
as well.
In all, we have the following formula in type conversion of pointer:
const
and Double Pointers
const
and Double PointersDouble pointer with const
works in a similar way. Remember that const
always works on the nearest type.
Now let's look at the following code. q has the the type of const int **, and &p has the type of int **, it seems work according to our previous inference, since a is not a constant and doesn't have constraint, but why there's an error?
It might seems confusing, but we can think about it in this way. Assume that the above code is correct, then *q has the type of const int *. If we have the following code, then it is a valid operation because &b also has the type of const int *.
But wait! What q points to is another pointer p, so the statement above is the same as p = &b
. Since p is a not a const
pointer, now we expose the memory of a constant b to a normal pointer p! This violate the rule of const
that there is no directly modification of a constant. So our code above is not correct. We can fix this in two ways, either mark p as const
or add another const
on q
.
In all, we have the following formula in type conversion of double pointer:
Last updated