C++ programming 3 min read

Pointers and references

A pointer stores an address, and * reads or writes what it points to. In firmware, a pointer to a fixed address is how C++ talks to hardware registers.

Five 4-byte memory cells from address 0x2000_0010 to 0x2000_0020. The int value at 0x2000_0010 holds 42. The pointer p at 0x2000_0020 holds the address 0x2000_0010, shown as an arrow from p to value. Dereferencing p, written *p, reads 42.
A pointer holds an address; dereferencing it reaches the value.

Addresses and values

&value takes the address of a variable, and *p follows a pointer to the value. A reference is a second name for an existing variable.

pointer.cppC++
#include <iostream>int main() {    int value = 42;    int* p = &value;   // p holds the address of value    *p = 7;            // write through the pointer    int& r = value;    // r is another name for value    r += 1;    std::cout << "value=" << value << " *p=" << *p << '\n';}
Output
value=8 *p=8

Pointers to hardware

Registers live at fixed addresses in the memory map. A volatile pointer makes sure every read and write really happens, because the hardware can change the value on its own.

gpio.cppC++
#include <cstdint>// STM32F103: GPIOA output data register (ODR) at 0x4001'080C.volatile std::uint32_t* const GPIOA_ODR =    reinterpret_cast<volatile std::uint32_t*>(0x4001'080C);void led_on() {    *GPIOA_ODR |= (1u << 5);   // drive PA5 high}