Follow+Star Public Account Number, don’t miss out on exciting contentAuthor | Mr.Deng Source | Embedded Intelligence Bureau
This article shares the intricacies of using <span>const</span>
with pointers in embedded C. As we all know, the flexibility of pointers is the core charm of C, but it is also a double-edged sword—carelessness can lead to memory overflow, data corruption, and other issues.
The addition of the <span>const</span>
keyword gives pointers the ability of “selective freedom”: it retains the dynamic operation of pointers while precisely controlling the modifiability of data. Today, we will reveal the core techniques of combining <span>const</span>
with pointers based on practical engineering scenarios, helping you write safer and more robust code.
1. Technical Essence: Three “Contracts” of const and Pointers
Before diving into applications, let’s clarify the three combinations of <span>const</span>
when modifying pointers (using <span>int</span>
type as an example):
Syntax | Pointer Mutability | Content Mutability | Core Meaning |
---|---|---|---|
<span>const int *p</span> |
✔️ | ❌ | Read-only data, flexible pointer |
<span>int *const p</span> |
❌ | ✔️ | Fixed address, data can be modified |
<span>const int *const p</span> |
❌ | ❌ | Completely read-only |
Memory Mnemonic:•<span><span>const</span></span>
on the left (<span>const T *p</span>
) → Data is immutable
•<span><span>const</span></span>
on the right (<span>T *const p</span>
) → Pointer is immutable
• Both sides have<span><span>const</span></span>
→ Double lock seal
2. Practical Scenarios: Five Highlights of const Pointers
Function Parameters: A Tool for Defensive ProgrammingScenario: Design a function to print the length of a string, ensuring that the internal content of the string is not modified.
size_t safe_strlen(const char *str) {
// str[0] = 'A'; // Compilation error! Modification of data is prohibited
size_t len = 0;
while (str[len] != '\0') len++;
return len;
}
Value:• Clearly defines the function’s responsibility: <span>const char *</span>
informs the caller that “this function will not modify your data”.
• Prevents internal misoperations: even if the function has complex logic, it cannot modify data through pointers.
Accessing Hardware Registers: A Mandatory Constraint on Address ImmutabilityScenario: Operate on the registers of embedded devices, requiring fixed pointer addresses but allowing data to be written.
#define HW_REG_ADDR 0x40000000
volatile uint32_t *const reg = (uint32_t *)HW_REG_ADDR;
void set_register() {
*reg = 0x55AA; // Correct: write data
// reg = (void*)0x50000000; // Compilation error! Address is immutable
}
Value:• Prevents the pointer from being accidentally modified, ensuring the absolute correctness of hardware operation addresses.
• The combination of <span>volatile</span>
and <span>const</span>
ensures that the address is fixed while avoiding compiler optimizations.
Embedded Configuration Table: Double Protection for Sensitive DataScenario: Store read-only configuration parameters for devices (such as baud rate, parity).
const struct UartConfig {
int baud_rate;
char parity;
} *const config_table = (const struct UartConfig*)0x8000;
void init_uart() {
// config_table->baud_rate = 115200; // Error: data cannot be modified
// config_table = NULL; // Error: pointer cannot be modified
set_uart(config_table->baud_rate, config_table->parity);
}
Value:• Both data and pointer are <span>const</span>
, preventing accidental overwriting of the configuration table at runtime.
• Mapped to a fixed memory address, suitable for configuration data stored in ROM or Flash.
Dynamic Memory Management: Preventing Pointer “Drift”Scenario: Allocate fixed blocks in a memory pool, ensuring that management pointers do not go out of bounds.
uint8_t memory_pool[1024];
uint8_t *const pool_start = memory_pool;
uint8_t *const pool_end = memory_pool + sizeof(memory_pool);
void* allocate_mem(size_t size) {
static uint8_t *current = memory_pool;
if (current + size > pool_end) return NULL;
void *ptr = current;
current += size;
return ptr;
}
Value:• <span>pool_start</span>
and <span>pool_end</span>
serve as boundary sentinels, prohibiting modification and ensuring the memory pool range remains constant.
String Constants: Avoiding Wild Pointer TrapsScenario: Define read-only global string constants.
const char *const LOG_HEADER = "[SYSTEM]: ";
void log_message(const char *msg) {
printf("%s%s\n", LOG_HEADER, msg);
// LOG_HEADER[0] = '('; // Error: data cannot be modified
// LOG_HEADER = "[ERROR]: "; // Error: pointer cannot be modified
}
Value:• Prevents string constants from being accidentally modified (which could otherwise trigger segmentation faults).
3. Advanced Techniques: The Game of const and Type Casting
Breaking through const restrictions? Beware of UB!Question: Can <span>const</span>
data be modified through other pointers?
const int a = 100;
int *p = (int*)&a;
*p = 200; // Undefined behavior (UB)! May crash or silently fail
Conclusion:• <span>const</span>
is a “gentleman’s agreement” among developers; breaking it can lead to unpredictable consequences.
Passing const through Multi-level PointersRules:<span>const</span><span> modifications should follow the "right to left" binding principle:</span><pre><code class="language-c">const int **pp1; // pp1 is mutable, *pp1 is mutable, **pp1 is immutable
int *const *pp2; // pp2 is mutable, *pp2 is immutable, **pp2 is mutable
int **const pp3; // pp3 is immutable, *pp3 is mutable, **pp3 is mutable
Application: Gradually constrain mutability in complex data structures (such as linked lists, trees).
4. Conclusion: The Engineering Philosophy of const Pointers
- Safety First: By checking at compile time, runtime errors are eliminated at the bud stage.
- Code as Documentation:
<span>const</span>
clearly conveys data usage permissions, reducing collaboration costs within teams. - Resource Contracts: In embedded and system-level development, const pointers are the “guardians” of hardware, memory, and data.
———— END ————● Column “Embedded Tools”● Column “Embedded Development”● Column “Keil Tutorials”● Selected Tutorials from the Embedded ColumnFollow the public accountReply “Join Group” to join the technical exchange group according to the rules, reply “1024” to see more content.Click “Read the Original” to see more shares.