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
From:manus_eiffel    Date:2007/12/13    Status: Suspended    Download   
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.

From:ericbe    Date:2007/12/13    Download   
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.

From:manus_eiffel    Date:2007/12/13    Download   
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?

From:ericbe    Date:2007/12/12    Download   
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.

From:alexk_es    Date:2007/12/12    Download   
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

From:manus_eiffel    Date:2007/12/12    Status: Analyzed    Download   
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?