Bug 17802 - Equal double member function calls results in <= expression returning false
Summary: Equal double member function calls results in <= expression returning false
Status: RESOLVED DUPLICATE of bug 323
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.3.3
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-10-03 09:21 UTC by Jonathan Knispel
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: 3.3.3
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
t.ii double toReal() version (95.67 KB, text/plain)
2004-10-03 09:24 UTC, Jonathan Knispel
Details
t.s double toReal() version (1.88 KB, text/plain)
2004-10-03 09:25 UTC, Jonathan Knispel
Details
t.ii float toReal() version (95.67 KB, text/plain)
2004-10-03 09:25 UTC, Jonathan Knispel
Details
t.s float toReal() version (1.87 KB, text/plain)
2004-10-03 09:26 UTC, Jonathan Knispel
Details
t.cc code to illustrate the bug (396 bytes, text/plain)
2004-10-03 09:28 UTC, Jonathan Knispel
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Knispel 2004-10-03 09:21:56 UTC
"a" and "b" are instances of a struct with identical values.  The struct has a 
member function named "toReal()" that returns a double value based on the 
result of a simple calculation.  "a.toReal() <= b.toReal()" returns false, 
which seems wrong.  If toReal() is redefined with a float return value, it 
returns true, as expected.  If I assign the results of the double toReal() 
calls to a pair of double variables and test the variables with <=, the 
problem goes away (workaround).  Stepping through the double version in gdb 
shows all the values to be as expected (identical), but the <= test fails.  
Evaluating "p a.toReal() <= b.toReal()" in gdb prints true. 
 
I'm using g++ 3.3.3 (SuSE GNU/Linux 9.1), but see the same behaviour on 3.4.2 
and 3.2.2 (Red Hat) as well. 
 
I've made the .ii and .s files available on the web at the URLs below, rather 
than including them here (they're long).  I've renamed the files to indicate 
whether they were compiled with double or float return values. 
 
http://www.csse.uwa.edu.au/~jonathan/t.cc 
http://www.csse.uwa.edu.au/~jonathan/t-double.ii 
http://www.csse.uwa.edu.au/~jonathan/t-double.s 
http://www.csse.uwa.edu.au/~jonathan/t-float.ii 
http://www.csse.uwa.edu.au/~jonathan/t-float.s 
 
[I've reordered the command sequence below for clarity] 
======== 
piehole[1021] g++ -v 
Reading specs from /usr/lib/gcc-lib/i586-suse-linux/3.3.3/specs 
Configured with: ../configure --enable-threads=posix --prefix=/usr 
--with-local-prefix=/usr/local --infodir=/usr/share/info 
--mandir=/usr/share/man --enable-languages=c,c++,f77,objc,java,ada 
--disable-checking --libdir=/usr/lib --enable-libgcj 
--with-gxx-include-dir=/usr/include/g++ --with-slibdir=/lib --with-system-zlib 
--enable-shared --enable-__cxa_atexit i586-suse-linux 
Thread model: posix 
gcc version 3.3.3 (SuSE Linux) 
======== 
piehole[1026] g++ -o t -save-temps t.cc 
piehole[1027] ./t 
Using double 
a < b false 
a <= b false 
ad < bd false 
ad <= bd true 
======== 
(edit t.cc changing "#if 1" to "#if 0") 
piehole[1038] g++ -o t -save-temps t.cc 
piehole[1039] ./t 
Using float 
a < b false 
a <= b true 
ad < bd false 
ad <= bd true 
======== 
piehole[1032] cat t.cc 
#include <sys/time.h> 
#include <iostream> 
 
using std::cout; 
 
 
#if 1 
 
typedef double RealType; 
const char* realTypeName = "double"; 
 
#else 
 
typedef float RealType; 
const char* realTypeName = "float"; 
 
#endif 
 
struct TimeVal : public timeval 
{ 
    TimeVal(RealType t) { 
        tv_sec = static_cast<unsigned int>(t); 
        tv_usec = static_cast<unsigned int>(1e6 * (t - tv_sec)); 
    } 
 
    RealType toReal() { return tv_sec + 1e-6 * tv_usec; } 
}; 
 
int 
main(int argc, 
     char** argv) 
{ 
    cout << "Using " << realTypeName << '\n'; 
 
    TimeVal a(2.1); 
    TimeVal b(2.1); 
 
    if (a.toReal() < b.toReal()) 
        cout << "a < b true\n"; 
    else 
        cout << "a < b false\n"; 
 
    if (a.toReal() <= b.toReal()) 
        cout << "a <= b true\n"; 
    else 
        cout << "a <= b false\n"; 
 
    RealType ad = a.toReal(); 
    RealType bd = b.toReal(); 
 
    if (ad < bd) 
        cout << "ad < bd true\n"; 
    else 
        cout << "ad < bd false\n"; 
 
    if (ad <= bd) 
        cout << "ad <= bd true\n"; 
    else 
        cout << "ad <= bd false\n"; 
}
Comment 1 Jonathan Knispel 2004-10-03 09:24:22 UTC
Created attachment 7263 [details]
t.ii double toReal() version
Comment 2 Jonathan Knispel 2004-10-03 09:25:22 UTC
Created attachment 7264 [details]
t.s double toReal() version
Comment 3 Jonathan Knispel 2004-10-03 09:25:55 UTC
Created attachment 7265 [details]
t.ii float toReal() version
Comment 4 Jonathan Knispel 2004-10-03 09:26:18 UTC
Created attachment 7266 [details]
t.s float toReal() version
Comment 5 Jonathan Knispel 2004-10-03 09:28:00 UTC
Created attachment 7267 [details]
t.cc code to illustrate the bug

Change the "#if 1" to "#if 0" to switch from double to float return values,
etc.
Comment 6 Andrew Pinski 2004-10-03 14:54:05 UTC

*** This bug has been marked as a duplicate of 323 ***