5

I'm developing for the AVR platform and I have a question. I don't want the floating point library to be linked with my code, but I like the concept of having analog values of the range 0.0 ... 1.0 instead of 0...255 and 0...1023, depending on even whether I'm using a port as an input or as an output.

So I decided to multiply the input/output functions' arguments by 1023.0 and 255.0, respecively. Now, my question is: if I implement the division like this:

#define analog_out(port, bit) _analog_out(port, ((uint8_t)((bit) * 255.0)))

will GCC (with the -O3 flag turned on) optimize the compile-time floating point multiplications, known at compile time and cast to an integral type, into integer operations? (I know that when using these macros with non-constant arguments, the optimization is not possible; I just want to know if it will be done in the other case.)

  • 1
    Shouldn't this be a multiplication, not a division? (`analog_out(7, 0.5)` becomes a write of `0.5*255` to port 7, rather than a write of 0 chopped from 1/510)... – Borealid Feb 12 '12 at 07:11
  • 3
    Try it and find out! `gcc -S` will produce an assembly dump. You probably want `-O2 -ffast-math` for this, not `-O3` (`-O3` turns on optimizations that are almost always a net *lose*, like over-aggressive inlining; it's meant to be used on the one file in which your program spends 90% of its time). – zwol Feb 12 '12 at 07:24
  • well, it's a library so programs will spend 90+% of their time in there ;) but anyways, thanks for the idea. –  Feb 12 '12 at 07:28
  • 3
    Why you folks are downvoting this question without reason? –  Apr 22 '13 at 08:36
  • ***Explain the damn downvotes!*** –  Jul 05 '13 at 20:50

2 Answers2

3

GCC should always do constant folding if you supply bit as a numeric literal. If you want the compiler enforce the constness, you could get away with something like this:

#define force_const(x) (__builtin_choose_expr(__builtin_constant_p(x), (x), (void)0))
#define analog_out(port, bit) _analog_out(port, force_const((uint8_t)((bit) * 255.0)))
fnl
  • 2,209
  • 19
  • 17
2

Generally, I think gcc -O2 will do all arithmetic on constants at compile time.
It won't convert it to integer arithmetic - just to a constant integer.

It may be dangerous to rely on, especially if other people maintain the code. A situation where passing a non-constant parameter to a macro results in an error isn't good.

ugoren
  • 16,023
  • 3
  • 35
  • 65
  • It doesn't result in an error, I just want it to be optimized away. –  Feb 12 '12 at 13:05