Ground Embedded KO Subscribe

Notes / C Language

Operators and conversions: where bugs hide

Integer division, implicit conversions and operator precedence. The causes of code that compiles but gives the wrong value.

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

Before it calculates, C brings the operands to a common type. If you do not know these rules, you write code that is syntactically fine and numerically wrong.

Integer division

3 / 4 is 0. Both are integers, so the fraction is dropped. Writing adc / 4095 * 3.3 to compute a voltage gives 0 almost every time. Multiply first, or convert to floating point.

float v = adc * 3.3f / 4095.0f;   // works as intended

Integer promotion

Even when you add two uint8_t values, the arithmetic is done in int. So with uint8_t a = 200, b = 100;, a + b is 300, and it becomes 44 the moment you store it back in a uint8_t. The same rules explain why comparing a signed value with an unsigned one turns a negative number into a very large positive one.

Precedence

In if (reg & MASK == 0), == is evaluated first, so it means reg & (MASK == 0). Do not be sparing with parentheses in conditions that mix in bit operations.

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 →