Problem
Pointer in C++ is confusing. The declaration of pointer makes it worser.
One classic problem of pointer declaration is as follows.
1 | |
So here are the problems:
- What’s the difference between this two statements?
- What does
constconstrains on each of them?
TL;DR
Case 1
1 | |
p1can be re-assigned another address but it must be an integer (in this case).- value of
acan be changed which will change the value of*p1as well (of course) - Whereas
*p1cannot be changed directly.
Case 2
1 | |
p2requires immediate initialization at declaration, which points it to a variable.p2cannot re-points to another address, which has to bea(in this case).*p2can be changed, which changes value ofa.acan has be changed.
Analysis
In this section we look into the declarations and see what’s happening in there. Let’s first try to translate them into human language:
As suggested in The C++ Programming Language by Bjarne, the declaration of a pointer is split by *, where the part on the right is the intrinsic property of the pointer and the part on the left describes what does the pointer points to.
Hence, Case 1 declares a pointer that points to a const int.
Case 2 declares a const pointer that points to an integer.
Now what we got is a pair of a pointer and a value. The problem actually is the relation between them and whether we can manipulate one with the other one.
Case 1:
const int * p1;
A pointer that points to a const int
-
Okay to assign
p1another addressp1here is a free pointer which can points to any variables of typeint( orconst int). So it’s okay to assign it another address as follows:1
2
3
4int a = 5; const int * p1 = &a; int b = 10; p1 = &10; // now *p1 = 10 -
Okay to change the value of the variable
p1points toIn this case,
p1points toa, which is only modified by keywordint. The value ofacan definitely be changed here, no matter what it is in the declaration ofp11
2
3int a = 5; const int * p1 = &a; int a = 10; // now *p1 = 10 -
*p1cannot be changed directlyIn declaration of
p1, it is supposed to point to a constant integer so it’s not cool to change the respective value from the side of the pointer.1
2
3int a = 5; const int * p1 = &a; *p1 = 10; // Invalid
Case 2: int * const p2
int * const p2 = &a;
A const pointer that points to an integer
-
p2cannot be assigned another address.constkeyword ensures that it points its initialization variable.1
2
3
4int a = 5; int * const p2 = &a; int b = 10; p2 = &b; // Invalid -
Okay to alter the value of
aThe reason is the same as 2nd bullet point in Case 1.
aisn’t constrained byconst1
2
3int a = 5; int * const p2 = &a; a = 10; // *p2 = 10 now -
Okay to modify the value of
*p2p2constantly points to a address, which shall hold aintvalue in this case sop2wouldn’t care if the value changes.1
2
3int a = 5; int * const p2 = &a; *p2 = 10 // a = 10 now