Hello! Welcome to your next lesson.
In our last session, we saw how pass-by-pointer allows a function to modify a caller's variables, a powerful and essential technique in C. We used an example of populating a CAN_Message_t struct, where a function was given full write access to the caller's data.
However, in many real-world scenarios, especially in safety-critical systems like the ones you develop, we need a more controlled approach. We often want the efficiency of passing a pointer to avoid copying large data structures, but we also want to guarantee that the function cannot modify the data. This is where the const keyword becomes indispensable for creating robust and clear APIs.
Today's lesson will focus on exactly that. We will apply const to pointers, distinguishing between a constant pointer, a pointer to a constant, and a constant pointer to a constant. Mastering this is crucial for both interviews and for writing safe, professional C code.
A Rule for Deciphering Declarations
Before diving into the variations, let's learn a simple and reliable technique for reading C declarations, often called the "right-to-left" or "spiral" rule. It's invaluable for quickly parsing complex pointer declarations under pressure.
constant pointer vs pointer on a constant value - Stack Overflow
The following resource introduces a simple rule for parsing C declarations. This will be our primary tool for understanding the different placements of const.
Read the answer starting with 'To parse complicated types...'. It introduces the right-to-left rule. Then, read the answer that begins 'How to read it? Follow the below simple step...' which applies this rule step-by-step. Focus on the method, not just the result.
The key takeaway is to start from the variable name and read outwards, applying * as "pointer to" and const as "constant". Let's use this rule to break down the three main scenarios.
Case 1: Pointer to a Constant
This is the most common use of const with pointers in function arguments. It is a promise that the function will not modify the data pointed to.
Declaration:const int *p;
or equivalentlyint const *p;
Reading it (right-to-left):
pis a...*...pointer to an...int...integer that is...const...constant.
So, p is a pointer to a constant integer.
Implications:
- You cannot change the value at the address
ppoints to (i.e.,*p = 10;is illegal). - You can change the pointer itself to point to a different address (i.e.,
p = &some_other_int;is legal).
This is the mechanism you'd use to pass a large configuration struct to a function for reading without allowing any modifications.
Let's examine some code snippets to solidify this.
Important Question Related to const pointer in C - Aticleworld
These examples from Aticleworld demonstrate the behavior of a pointer to a constant. Pay attention to which operations succeed and which fail.
Analyze 'Question 3' and 'Question 4'. In Question 3, notice that incrementing the pointer (pcName++) is allowed. In Question 4, notice that attempting to modify the data through the pointer (pcName[0] = 'A') results in a compilation error.
An important subtlety: const char *p means the data is constant as far as p is concerned. If the original data was not declared const, it can still be modified through other non-const pointers or directly by its variable name.
Case 2: Constant Pointer
This type of pointer is less common in function parameters but is very useful for representing fixed hardware addresses.
Declaration:int * const p;
Reading it (right-to-left):
pis a...const...constant...*...pointer to an...int...integer.
So, p is a constant pointer to an integer. Because const directly follows the variable name, it applies to the pointer itself.
Implications:
- You can change the value at the address
ppoints to (i.e.,*p = 10;is legal). - You cannot change the pointer to point to a different address (i.e.,
p = &some_other_int;is illegal). Aconstpointer must be initialized at declaration and cannot be reassigned.
This is ideal for modeling a memory-mapped hardware register, where the address is fixed, but you need to read from or write to it. For example:volatile uint32_t * const UART0_TX_REG = (uint32_t *)0x4000C000;
Let's see the compiler error this produces.
Important Question Related to const pointer in C - Aticleworld
This example shows what happens when you try to modify a constant pointer.
Examine 'Question 5'. The code attempts to increment the pointer itself, which is declared as char * const. As the explanation notes, this is illegal and results in a compilation error.
Case 3: Constant Pointer to a Constant
This is the most restrictive form, combining the limitations of the previous two cases.
Declaration:const int * const p;
Reading it (right-to-left):
pis a...const...constant...*...pointer to an...int...integer that is...const...constant.
So, p is a constant pointer to a constant integer.
Implications:
- You cannot change the value at the address
ppoints to (*p = 10;is illegal). - You cannot change the pointer to point to a different address (
p = &some_other_int;is illegal).
This is useful for a fixed pointer to a piece of read-only data, such as a pointer to a specific entry in a constant calibration table stored in ROM.
The compiler will prevent any modification of the pointer or the data it points to.
Important Question Related to const pointer in C - Aticleworld
This final example from Aticleworld demonstrates the doubly-restrictive nature of a constant pointer to a constant.
Look at 'Question 6'. The declaration const char *const pcName makes both the pointer and the data it points to immutable. The code attempts to increment the pointer, which rightly fails.
Summary and Practice
The different combinations can be confusing, but they follow a consistent logic. This table provides a quick visual summary.

Now, let's put it all together. The following resource provides a single function that uses all three types of const pointers, plus a non-const pointer. Before looking at the comments in the code, try to predict which lines are legal and which will cause a compilation error.
constant pointer vs pointer on a constant value - Stack Overflow
This code snippet from a Stack Overflow answer is an excellent exercise. It puts all the pointer types we've discussed side-by-side in a single function.
Focus on the code within the Foo function. For each of the four parameters (ptr, ptrToConst, constPtr, constPtrToConst), analyze the two operations performed on it. Predict whether each line will compile or result in an error based on the rules we've just covered. Then, read the comments to check your predictions.
Conclusion
You have now analyzed the critical role of const in pointer declarations, a topic that frequently appears in C programming interviews. Understanding these distinctions is a hallmark of a programmer who thinks carefully about API design, efficiency, and safety.
Key Takeaways:
- The right-to-left rule is a reliable method for deciphering complex C declarations.
- Pointer to
const(const int *p): You can change the pointer, but not the data it points to. Use this for efficient, read-only access to data in function calls. constPointer (int * const p): You can change the data, but not the pointer itself. Use this for fixed hardware addresses.constPointer toconst(const int * const p): You can change neither the pointer nor the data. Use this for fixed pointers to read-only configuration data.
In our next lesson, we will investigate a common and dangerous pointer-related bug. We will predict the behavior of code that returns a pointer to a local (stack) variable and explain the resulting undefined behavior. This will tie together our knowledge of pointers with the program's memory layout and function call stack.