How to force the GCC compiler to compute constant values ​​at compile time?


I have the following code (CPU Atmel AVR ATmega64A):

#define UO_ADC1023  265
#define UREF_180V   (1023*180/UO_ADC1023)
if(ADC > UREF180) {do_something();}

This should evaluate UREF_180V as 694.87... and than this value should be rounded (better) to 695 or floored (poorer) to 694 to be compared to ADC register.

However I have integer overflow warning at compile. As per this I suppose that compiler generating code which calculates (1023*180/UO_ADC1023) at the run time which is very bad in my case.

I'd like to avoid to calculate those constants by my self (#define UREF_180V 695 in this case I could be sure that they are really literals) to make the code more flexible and readable. I'd like also to be able to check those values after the compiler.

So the questions are:

  1. Is there any possibility to force GCC compiler to calculate such constants at compile time?

  2. How to check this calculated value?

Macros are inserted at the place of invokation, where their content can later be compiled.

In C++11 you can evaluate expressions at compile time with constexpr, like this:

constexpr auto UREF_180V = 1023*180/UO_ADC1023;

Due to all of the numbers being ints the result of this is 694. To properly round it you would have to change one of the values to a floating point number and create a constexpr rounding function, which can be invoked at compile time.

As for checking the number you could use static_assert(695 == UREF_180V, "");.

To compile C++11 code add -std=c++11 to your compiler options. (You probably have to switch to a C++ project, and I'm not entirely certain AtmelStudio supports C++11, if not I'm sorry)