Compilers do no such thing: they do not assume that floating point + and * are associative, because they most definitely aren't. Roundoff errors are different, and the effect of this can be huge.
Consider (a+b)+c vs a+(b+c). Now suppose a is 1, b is 2.0^60, c is -b. The first expression evaluates to 0, the second evaluates to 1.
Scientific and engineering code is carefully designed for numerical stability and compilers must not mess this up.
gcc has a "fast math" flag you can use if you don't care about the accuracy of your results.