I tried several of the suggestions with the following results:
1) x = y * 100 * 0.25; // float lib included
2) x = 100 * 0.25 * y; // float lib included
3) x = y * (100 * 0.25); // float lib included
4) x = y * (int)(100 * 0.25); // float lib NOT included
5) static int x = 100 * 0.25; // float lib NOT included
6) int x = 100 * 0.25; // float lib included
For the first three, apparently the compiler is performing the
multiply at run time because its not recognizing that the result is
going to be converted into an integer (x and y are integers, BTW).
It is just as likely that the compiler is performing the multiply
at compile time, but not performing the cast at compile time.
In general int(x*a) is not equal to x*int(a) even if x is an integer.
It is a lot to ask of the compiler that is recognize that
even though 25. is a floating point constant its value is
integral. The float lib is still needed to compute
x*25.
Adding the cast on 4 is enough of a hint for the compiler to catch on
and do the math at compile time.
Or possibly allows the cast from 25. to 25 which removes the need
for the float lib.
Using the multiply in a static
initializer in 5 forces the compiler to try to fully evaluate the
expression at compile time since the expression must be constant.
But since an initializer for a local doesn't have to be constant, for 6
the compiler performs the multiply at run time.
The compiler could perform this multiply at run time but it does not
have to. Again you seem to be assuming that if the float lib is loaded
the multiply must be done at run time. This may or may not be true.
So at least now I understand what's going on. But I still don't know
what the C standard says about it. I'm pretty sure that 5 will either
work or generate an error message (i.e., "Initializer must be
constant..."). But can I count on 4 always working, or is it
implementation dependant?
If you mean can you count on 4 leading to x having the value 25*y, the answer
is yes. If you mean can you count on 4 forcing the evaluation of (100 * 0.25)
at compile time the answer is no, the compiler may evaluate
this at compile time but does not have to. If you mean can you count on 5
leading to the float lib not being loaded the answer is no. The standard
is silent on when the float lib should be loaded, or indeed if there
is such a beast as a float lib in the first place. The implementation
could choose to load the float lib whenever there is a full moon.
More likely in practice, the implementation may use heuristics to
decide when to load float lib. Since not loading float lib when
needed is a far more serious error than loading float lib when not
needed the heuristics will be chosen to favour the latter.
-William Hughes