Ready to practice?
Sign up to access interactive coding exercises and track your progress.
Const Correctness with Pointers
Distinguish between pointers to const data and const pointer variables.
Pointers and Const
Consider this code snippet:
int main()
{
int health{100};
int* ptr{&health}; // ptr is a normal (non-const) pointer
int mana{50};
ptr = &mana; // We can point at another value
*ptr = 75; // We can change the value at the address being held
return 0;
}
With normal (non-const) pointers, we can change both what the pointer is pointing at (by assigning a new address) and the value at the address being held (by assigning to the dereferenced pointer).
However, what happens if the value we want to point at is const?
int main()
{
const int maxHealth{100}; // maxHealth is now const
int* ptr{&maxHealth}; // Compile error: cannot convert from const int* to int*
return 0;
}
This snippet won't compile. We can't set a normal pointer to point at a const variable. This makes sense: a const variable is one whose value cannot be changed. Allowing the programmer to set a non-const pointer to a const value would allow dereferencing and changing the value, violating constness.
Pointer to Const Value
A pointer to a const value (sometimes called a pointer to const) is a (non-const) pointer that points to a constant value.
To declare a pointer to const, use the const keyword before the pointer's data type:
int main()
{
const int maxHealth{100};
const int* ptr{&maxHealth}; // Valid: ptr is pointing to a "const int"
*ptr = 200; // Error: we can't change a const value
return 0;
}
In this example, ptr points to a const int. Because the data type being pointed to is const, the value being pointed to can't be changed.
However, because a pointer to const is not const itself (it just points to a const value), we can change what the pointer is pointing at:
int main()
{
const int maxHealth{100};
const int* ptr{&maxHealth}; // ptr points to const int maxHealth
const int maxMana{200};
ptr = &maxMana; // Valid: ptr now points at const int maxMana
return 0;
}
Just like a reference to const, a pointer to const can point to non-const variables too. A pointer to const treats the value being pointed to as constant, regardless of whether the object at that address was initially defined as const:
int main()
{
int health{100}; // Non-const
const int* ptr{&health}; // ptr points to a "const int"
*ptr = 75; // Error: ptr points to a "const int" so we can't change through ptr
health = 75; // Valid: the value is still non-const when accessed through health
return 0;
}
Const Pointers
We can also make a pointer itself constant. A const pointer is a pointer whose address cannot be changed after initialization.
To declare a const pointer, use the const keyword after the asterisk:
int main()
{
int health{100};
int* const ptr{&health}; // const after the asterisk means this is a const pointer
return 0;
}
In this case, ptr is a const pointer to a (non-const) int value.
Just like a normal const variable, a const pointer must be initialized upon definition, and this value can't be changed:
int main()
{
int health{100};
int mana{50};
int* const ptr{&health}; // Valid: the const pointer is initialized to health's address
ptr = &mana; // Error: once initialized, a const pointer cannot be changed
return 0;
}
However, because the value being pointed to is non-const, it's possible to change that value via dereferencing the const pointer:
int main()
{
int health{100};
int* const ptr{&health}; // ptr will always point to health
*ptr = 75; // Valid: the value being pointed to is non-const
return 0;
}
Const Pointer to a Const Value
Finally, it's possible to declare a const pointer to a const value by using the const keyword both before the type and after the asterisk:
int main()
{
int score{100};
const int* const ptr{&score}; // A const pointer to a const value
return 0;
}
A const pointer to a const value cannot have its address changed, nor can the value it's pointing to be changed through the pointer. It can only be dereferenced to get the value it's pointing at.
Pointer and Const Recap
To summarize, you only need to remember 4 rules, and they're pretty logical:
-
A non-const pointer (e.g.,
int* ptr) can be assigned another address to change what it's pointing at -
A const pointer (e.g.,
int* const ptr) always points to the same address, and this address cannot be changed -
A pointer to a non-const value (e.g.,
int* ptr) can change the value it's pointing to. These cannot point to a const value -
A pointer to a const value (e.g.,
const int* ptr) treats the value as const when accessed through the pointer, and thus cannot change the value it's pointing to. These can be pointed to const or non-const lvalues (but not rvalues, which don't have an address)
Keeping the declaration syntax straight can be challenging:
- A
constbefore the asterisk (e.g.,const int* ptr) is associated with the type being pointed to. Therefore, this is a pointer to a const value, and the value cannot be modified through the pointer - A
constafter the asterisk (e.g.,int* const ptr) is associated with the pointer itself. Therefore, this pointer cannot be assigned a new address
int main()
{
int score{100};
int* ptr0{&score}; // Points to an "int" but is not const itself. We can modify the value or the address
const int* ptr1{&score}; // Points to a "const int" but is not const itself. We can only modify the address
int* const ptr2{&score}; // Points to an "int" and is const itself. We can only modify the value
const int* const ptr3{&score}; // Points to a "const int" and is const itself. We can't modify the value nor the address
// If the const is on the left side of the *, the const belongs to the value
// If the const is on the right side of the *, the const belongs to the pointer
return 0;
}
Const Correctness with Pointers - Quiz
Test your understanding of the lesson.
Practice Exercises
Pointers and Const
Master the four combinations of pointers and const: non-const pointer to non-const, pointer to const, const pointer, and const pointer to const. Learn when to use each type.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!