Search code examples
cc-preprocessorcortex-m

If I use a fixed formula in a #define, is it less efficient than using a number?


I am working my way through some legacy code at work for a Cortex-M3, written in C on Keil µVision.

In a function to record values from an ADC, a scaling factor is used to convert from bits back to volts.

My question revolves around the scaling factor, which is defined in the header file:

#define INPUT_VALUE_MAX (uint16_t)((1<<12)-1)

So this equals 4095, which makes sense, because it is a 12-bit ADC. The question I have is whether defining the value "INPUT_VALUE_MAX" as a formula means that every time it is used, the microcontroller has to re-calculate the value.

Simply, does:

#define INPUT_VALUE_MAX (uint16_t)((1<<12)-1)

take more processing time than:

#define INPUT_VALUE_MAX (uint16_t)4095?

Thanks in advance for any help anyone can offer!


Solution

  • No, it does not take any run-time processing time. The whole macro is an integer constant expression, meaning it will get calculated at compile-time.

    If you look at the generated assembly, you'll see that the expression is replaced by the constant 4095.


    A constant expression is defined by C like this, C11 6.6:

    A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.

    Constraints

    Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.

    Each constant expression shall evaluate to a constant that is in the range of representable values for its type.

    /--/

    An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.