Ground Embedded KO Subscribe

Notes / C Language

The preprocessor and macros

#define, conditional compilation, header guards. The traps macros set and how to use them safely.

GROUND EMBEDDED · NOTEC Language 11Preprocessor and macros 1volatile uint32_t *ODR 2 = (uint32_t*)0x40020014; 3*ODR |= (1u << 5); 4while (1) { 5 if (flag) toggle(); 6}

The preprocessor is a text-replacement step that runs before compilation. #include pastes in a file's contents and #define substitutes a value for a name.

Macro traps

#define SQ(x) x * x
SQ(a + 1)      // expands to a + 1 * a + 1
#define SQ(x) ((x) * (x))   // wrap in parentheses

Pass i++ to a macro that uses its argument twice and it increments twice. Macros that calculate are safer rewritten as static inline functions.

Conditional compilation

#ifdef DEBUG
  log_printf("adc=%u\n", adc);
#endif

Code is included or left out depending on board revision or debug build. Overused, nobody can tell which combination is really built, so gather the switches in one configuration header.

Header guards

They stop the same header being included twice and its definitions colliding.

#ifndef MOTOR_H
#define MOTOR_H
...
#endif
FREE PDFGet the 3 free ebooksIf you want to keep reading this topic as one book: BLDC motor control, serial communication and sensors at book length. PDFs are in Korean.Get them free →