<p>The C99 and C11 define precisely what happens when the host platform can only conveniently compute to a higher precision than that of <code>float</code> and <code>double</code>. The earlier C89 (or “ANSI”) C standard did not. In C99 or C11, the compiler defines <code>FLT_EVAL_METHOD</code> to 1 or 2, which tells the programmer that floating-point constants and operations are going to be interpreted to a higher precision than that of their types.</p>

<p>This was implemented in GCC in the patch discussed in <a href="https://gcc.gnu.org/ml/gcc-patches/2008-11/msg00105.html" rel="nofollow">this message</a>.
The option <code>-fexcess-precision=standard</code> provided by the patch is enabled by default in C99 and C11, but not enabled in “ANSI” (C89) mode.</p>

<p>It does not make too much sense to try to interpret what the compiler does in C89 mode: it's a bit fuzzy, with the value of floating-point variables changing without assignments to them, or changing between optimization levels, as described in <a href="http://arxiv.org/abs/cs/0701192" rel="nofollow">this report</a>. In C99 mode, with <code>FLT_EVAL_METHOD</code> defined by the compiler to <code>2</code>, the difference <code>2.335 - 2.334</code> is computed by the compiler as a 80-bit floating-point number, the difference between the 80-bit FP representation of 2335/1000 and the 80-bit FP representation of 2334/1000. This number happens to be different from the 80-bit representation of 1/1000. This is why the second version of your test program behaves as it does without <code>-ansi</code>. In the first version of your test program, the assignments to <code>double</code> variables cause the numbers to be rounded to double-precison (64-bit) floating-point values. They are equal after both having been rounded thus.</p>
gcc floating point with and without -ansi disparity
<p>Consider the two programs. First one prints "Unequal" on gcc 5.3.0 (target: i686-pc-cygwin). When -ansi option is used "Equal" is printed.</p>

<pre><code>int main () {
        double d = 2.335 - 2.334;
        double q = 0.001;
        if (d == q) {
            printf ("Equal\n");
        } else {
            printf ("Unequal\n");
        }
    return 0;
 }
</code></pre>

<p>Second one prints "Unequal" with or without -ansi option.</p>

<pre><code>int main () {
    if (2.335 - 2.334 == 0.001) {
        printf ("Equal\n");
    } else {
        printf ("Unequal\n");
    }
    return 0;
}
</code></pre>

<p>What is the source of disparity?
Of course it is a common knowledge that real numbers should not be tested for equality. I understand the implications of IEEE754 standard on the (im-)precision of calculations involving floating point. However, to my best understanding, those two programs should be semantically equivalent and give the same results. </p>

<p>Is there some implicit conversion going on in the first one in C89 mode that was removed in C99?</p>