Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 631986 - gcc "-ansi" causes double d = 0.1; if (d != 0.1) { fail } to trigger
Summary: gcc "-ansi" causes double d = 0.1; if (d != 0.1) { fail } to trigger
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: rawhide
Hardware: All
OS: Linux
low
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 631403
TreeView+ depends on / blocked
 
Reported: 2010-09-08 19:48 UTC by Caolan McNamara
Modified: 2010-09-21 19:18 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2010-09-08 20:44:18 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
gcc -m32 -ansi test.c (deleted)
2010-09-08 19:48 UTC, Caolan McNamara
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Gentoo 318393 0 None None None Never

Description Caolan McNamara 2010-09-08 19:48:25 UTC
Created attachment 446074 [details]
gcc -m32 -ansi test.c

Version-Release number of selected component (if applicable):
gcc-4.5.1-3.fc14

How reproducible:
100%

Steps to Reproduce:
1. gcc -m32 -ansi test.c
2. ./a.out
where test.c is

#include <stdio.h>

int main(void)
{
    double d=0.1;

    if(d!=0.1)
	printf("unexpected!\n");

    return 0;
}
  
Actual results:
"unexpected!"

Expected results:
nothing

Additional info:
caught by icu make check, so this didn't happen earlier in the F-14 cycle

without "-ansi" this behaves as expected. Seems odd that -ansi has an effect on this.

Comment 1 Denis Arnaud 2010-09-08 20:09:07 UTC
I'm not sure about the C/C++ standards, but it is usually a bad idea to strictly compare two floats or doubles. It is recommended to compare that two floats/doubles are roughly equal, with a given accuracy of epsilon (e.g., 1e-3).

That statement comes from years of experience with several major OLTP applications on different Unices (HP-UX, SunOS, Linux) running on different hardware platforms in production.

Sometimes, a given application, where we compared two floats, runned two or three years in production with 10tps (transactions per second) 24x7, without any problem. Then, suddenly, nobody could explain why, but the application started to fail: the floats became no longer equal (and sometimes, not not equal at the same time!).

Hence, we have implemented the epsilon trick everywhere we needed to compare two floats/doubles. And we have been able to sleep quietly ever since...


That's just my $0.02

Comment 2 Jakub Jelinek 2010-09-08 20:44:18 UTC
i?86-linux is a FLT_EVAL_METHOD 2 target (because of the insane i?87 hw), and that requires that for strict standard conformance all operations and constants are supposed to be evaluated in precision of long double.  d is a double variable, so the constant needs to be casted to double precision, so it is evaluated as
double d = 0.1;
if ((long double) d != 0.1L)
and those constants are different.
If you write it as if(d!=(double)0.1), it will be equal.
GCC 4.5 implement this standard conformant mode.  There is the -fexcess-precision={fast,standard} option to select behavior, with standard being the default for -std={c89,c9*,iso*} and fast otherwise.  Of course for FLT_EVAL_METHOD 0 targets like x86-64 this doesn't make difference.
What Denis wrote above is a reasonable recommendation in any case.

Comment 3 Steven R. Loomis 2010-09-21 19:18:43 UTC
Fixed in ICU upstream http://bugs.icu-project.org/trac/ticket/7932 ( Should ICU be an available external bug type here?)


Note You need to log in before you can comment on or make changes to this bug.