I'm using avr-gcc on a 16-bit target platform
I'd like to do something like this:
#define F_CPU 16000000
#define MIN_UPDATES_PER_REV 100
#define MAX_RPM 10000
#define UPDATE_PERIOD_cy ( F_CPU*60 / (MIN_UPDATES_PER_REV*MAX_RPM) )
As expected, I get an overflow error because MIN_UPDATES_PER_REV*MAX_RPM evaluates to 0xf4240:
bldc.h:9:40: warning: integer overflow in expression [-Woverflow]
#define UPDATE_PERIOD_cy ( F_CPU*60 / (MIN_UPDATES_PER_REV*MAX_RPM) )
^
Things work out if I force the constants to 32 bits and convert back to uint16_t after folding, although I lose the benefits of -Woverflow:
#define UPDATE_PERIOD_cy (uint16_t)( (uint32_t)F_CPU*60 / ((uint32_t)MIN_UPDATES_PER_REV*MAX_RPM) ))
Can I force gcc to handle large intermediate values during constant folding?
Can I force the preprocessor to do constant folding for me?
Are there best practices I should know about?
No you cannot do this. General C rules are always applied. Meaning
MIN_UPDATES_PER_REVwill be evaluated to uint16 andMAX_RPMto uint8. The result of multiplication doesn't fit into uint16and you get the -Woverflow.The preprocessor only does the macro substitution and GCC does the constant folding. If the question is about forcing GCC to do the constant folding, no you cannot but GCC will do the constant folding even without optimization flag.
This is a subjective question. (I think you already use best way to do with casting. As it is optimized at compile time, you do not have an execution overcost).