Reputation: 1033
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:
Is there any possibility to force GCC compiler to calculate such constants at compile time?
How to check this calculated value?
Upvotes: 1
Views: 2261
Reputation: 799420
int
on AVR is 16-bit. Tell the compiler to use long
instead (since 1023 * 180 will overflow).
#define UREF_180V (1023L * 180 / UO_ADC1023)
Upvotes: 3
Reputation: 560
see the -fmerge-all-constants command, -fgcse, -fsee, or better, see here: https://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Optimize-Options.html
nonetheless, the integer overflow can be part of an semantic error in your code as welternsturm mentioned
Upvotes: 2
Reputation: 2162
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 int
s 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)
Upvotes: 3