C Programming Basics

#define GPIO_BASE 0x40020000u
volatile uint32_t *const odr =
    (volatile uint32_t *)(GPIO_BASE + 0x14);
*odr |= 1u << 5;

A microcontroller output register is declared and used as above. Which of the following correctly describes this declaration?

  1. AThe value of *odr cannot be modified, while odr itself may be changed by interrupts, so it is read again every time it is used
  2. BBecause volatile is added, the read-modify-write of *odr |= 1u << 5 becomes a single operation that cannot be interrupted
  3. CThe address odr points to cannot be changed, and reads and writes through odr are not removed but performed exactly as many times as written
Show answer and explanation

Answer: C. The address odr points to cannot be changed, and reads and writes through odr are not removed but performed exactly as many times as written

const is to the right of *, so the pointer odr itself cannot be changed and always points to the same register address. The uint32_t it points to is volatile, so the compiler does not remove or merge reads and writes of *odr, and performs as many accesses as written. However, volatile does not make operations atomic, so an interrupt can occur between the read and the write of *odr |= …. When the same register is also manipulated by an interrupt handler, disable interrupts for the duration or use a dedicated bit-set register.

  • A. This reads the targets of const and volatile the other way round. const applies to the pointer itself and volatile to what it points to.
  • B. volatile only keeps accesses from being removed; it does not make the sequence from read to write atomic.
  • C. Correct. The pointer itself is const, and the register it points to is volatile.
Practice this topic Back to topic

Books on C Programming Basics Ad

As an Amazon Associate I earn from qualifying purchases.

More C Programming Basics questions

  1. Which of the following describes undefined behavior as defined by the C standard?
  2. int and unsigned int are 32 bits. Which of the following is undefined behavior according to the C standard?
  3. When the function above is compiled with gcc with optimization enabled, the check if (p == NULL) may be removed. Which of the following is the reason?
  4. Which of the following is what the C standard specifies about the size of the int type?
  5. In embedded programs, variables that hold the value of a 32-bit peripheral register are often declared with uint32_t from stdint.h rather than unsigned int. Which of the following is the main reason?