To understand this, you need to know the difference between the order of evaluation and priority.
Take your expression, for example:
Vdda = 3.3 * (*VREFINT_CAL) / ADC_DR->DATA;
Priority (and parentheses) determines how the abstract syntax tree (AST) is created. The result will be something like this:
= Vdda * 3.3 / * VREFINT_CAL -> ADC_DR DATA
The evaluation order is determined by the presence of sequence points. And your code has only one point in the sequence, at the end of the expression ( ; ).
Thus, the evaluation procedure for any subexpression is not specified. That is, the compiler can perform any intermediate calculations and memory access in any order that it considers necessary. Some people like to think that subexpressions are evaluated from left to right, but thatβs not how the language works.
This usually doesn't matter, but two of your subexpressions are volatile ( *VREFINT_CAL and ADC_DR->DATA ), so the order matters. It may not matter to you, but it certainly does matter to the compiler.
To solve the problem, use temporary ones, just to add an intermediate point in the sequence:
short a = *VREFINT_CAL; unsigned b = ADC_DR->DATA; Vdda = 3.3 * a / b;
source share