An optimisation that could change the result (even by the smallest possible amount) is not a safe optimisation. As a general rule, unless the build script tells it otherwise, a compile won't perform an optimisation that could make the optimised version give a different result from the basic one.
Of course you may decide it is safe enough, in which case you might find your compiler has an option to tell it that you would like such optimisations to be considered. Stepping away from arithmetic for a moment, variable aliasing is another example of this. If your code could potentially update a value several ways through pointer jiggery-pokery a compile may decide certain register based optimisations are not safe, and there are often directives you can give to tell the compile that it can consider these optimisations as you are sure the code does nothing that would make them a problem (the compile can't decide this for itself as that would potentially take for ever due to the "halting" problem).
Obviously they can't do whatever they want but they can decide if they want to store variables in registers or main memory, they can change the order of a variety of operations, etc. Does C specify order of evaluation with multiplication? If so I wasn't aware of that. But you'll still have some compilers giving you 32 bit precision on intermediate results and some giving you 80 bits.
> they can decide if they want to store variables in registers or main memory, they can change the order of a variety of operations, etc.
As long as they follow the "as if rule", which states that any transformations that is done to code that does not invoke undefined behavior will produce the same final result as if the transformations were not done. Reordering floating point multiplications does not follow this rule.
(Watching stuff in a debugger doesn't count for this rule)
1. Are you saying that multiplications have a specified order? I asked that but didn't get a response.
2. The compiler is allowed to either leave the float inside the FPU or store it back to main memory after each operation, is it not? These give different results.
Somewhere around here I have a chart of the differences in floating point outputs of different GCC versions. And no, fastmath is not on.
Yes. Multiplication is left associative. I'm not sure that C defines the precision of floating point operations, although I think it sets an upper bound. I may be wrong, and I think that the C99 spec (optionally?) pushes compilers to conform to the iee754
Comments
Why does it being different matter? Compilers can do all kinds of things that change answers.
Because consistency matters.
An optimisation that could change the result (even by the smallest possible amount) is not a safe optimisation. As a general rule, unless the build script tells it otherwise, a compile won't perform an optimisation that could make the optimised version give a different result from the basic one.
Of course you may decide it is safe enough, in which case you might find your compiler has an option to tell it that you would like such optimisations to be considered. Stepping away from arithmetic for a moment, variable aliasing is another example of this. If your code could potentially update a value several ways through pointer jiggery-pokery a compile may decide certain register based optimisations are not safe, and there are often directives you can give to tell the compile that it can consider these optimisations as you are sure the code does nothing that would make them a problem (the compile can't decide this for itself as that would potentially take for ever due to the "halting" problem).
They can't do it on code that doesn't invoke undefined behavior. This is not undefined behavior.
Obviously they can't do whatever they want but they can decide if they want to store variables in registers or main memory, they can change the order of a variety of operations, etc. Does C specify order of evaluation with multiplication? If so I wasn't aware of that. But you'll still have some compilers giving you 32 bit precision on intermediate results and some giving you 80 bits.
> they can decide if they want to store variables in registers or main memory, they can change the order of a variety of operations, etc.
As long as they follow the "as if rule", which states that any transformations that is done to code that does not invoke undefined behavior will produce the same final result as if the transformations were not done. Reordering floating point multiplications does not follow this rule.
(Watching stuff in a debugger doesn't count for this rule)
1. Are you saying that multiplications have a specified order? I asked that but didn't get a response.
2. The compiler is allowed to either leave the float inside the FPU or store it back to main memory after each operation, is it not? These give different results.
Somewhere around here I have a chart of the differences in floating point outputs of different GCC versions. And no, fastmath is not on.
Yes. Multiplication is left associative. I'm not sure that C defines the precision of floating point operations, although I think it sets an upper bound. I may be wrong, and I think that the C99 spec (optionally?) pushes compilers to conform to the iee754