PR# 13754 Comparing NaN in melted code
Problem Report Summary
Submitter: ericbe
Category: Compiler
Priority: Medium
Date: 2007/12/12
Class: Bug
Severity: Serious
Number: 13754
Release: 6.1.7.1223
Confidential: No
Status: Suspended
Responsible:
Environment: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; InfoPath.1; .NET CLR 3.0.04506.648)
Synopsis: Comparing NaN in melted code
Description
Comparing NaNs together in frozen and finalized modes returns False as specified in http://en.wikipedia.org/wiki/NaN. However, it returns True in melted mode. The same behavior was observed in ISE 5.7.
To Reproduce
local nan: DOUBLE p: MANAGED_POINTER do -- Binary representation of IEEE 754 'NaN'. -- See: http://en.wikipedia.org/wiki/IEEE_754 create p.make (8) p.put_natural_8 (0, 0) p.put_natural_8 (0, 1) p.put_natural_8 (0, 2) p.put_natural_8 (0, 3) p.put_natural_8 (0, 4) p.put_natural_8 (0, 5) p.put_natural_8 (255, 6) p.put_natural_8 (127, 7) nan := p.read_real_64 (0) print (nan) print ("%N") print (nan /= nan) print ("%N")
Problem Report Interactions
I misread your message for the comparison you are doing. Indeed the comparison nan /= nan should always return True since they are indeed different and this is what I've observed. I think you were thinking of evaluating 'nan = nan' which is indeed supposed to return False and not True. I've verified that it works fine with VS 2005, but with MSVC++ 6.0 it is going to return True regardless of the option we provide (it does not have /fp, it is /Op instead but it does not change anything). And this is why the melted code behaves incorrectly (since we compile our interpreter with MSVC++ 6.0). Ideally we should compile against VS 2005 on 32-bit, but we unfortunately need 6.0 for backward compatibility.
The doc that Alexander found says that the default in /fp:precise. So even if I were using some C compiler flags (which I don't, apart from those set by EiffelStudio itself), this won't explain why I get the correct behavior. You should rather focus on why you get the wrong behavior.
We are using the default option (i.e. we do not specify any option), so I don't understand why you get a different behavior. Are you sure you are not setting some C compiler flags in your project?
I'm using MSVC 7.1. According to http://en.wikipedia.org/wiki/NaN, it looks like 'nan=nan' should return false, so your C compiler (and hence the melted code) is wrong. I know that having 'nan=nan' returning false violates a lot of assertions in Eiffel code, but I think that we are better off following IEEE 754 specification and rewrite our assertions accordingly than inventing a new specification incompatible with the rest of the world. But I guess this could be discussed at ECMA. Anyway, it looks like, according to what Alexander showed us, I'm using the default option (i.e. /fp is assumed to be 'precise') and you're not.
When compiling with Microsoft Visual C++, the compiler option /fp controls the behaviour of the generated code, and comparison of NaNs in particular. The details can be found at http://msdn2.microsoft.com/en-us/library/e7s85ffb(VS.80).aspx
I believe it has something to do with the C compiler. In my test, see eweasel test#melt080, I always get True regardless of the compilation mode. Since we compile the code of the runtime where the byte code is interpreted, I'm not surprised that you get True, since my C compiler always reports True. In workbench and final mode, then your C compiler is producing a different answer. So which C compiler are you using and on which platform?