On Windows I have found that a program I wrote fails when compiled with -O1 and -O2 but runs fine with -O0. The program behaves correctly on Linux and Solaris with or without optimizations.
The place it starts behaving differently on Windows is where two numbers (which should be equal) are failing a greater than or equal to (>=) if statement, but on Solaris and Linux it passes. My first thought was that this had to do with floating point representation differences on the systems but it doesn't appear to be. It appears to be a compiler error. The first thing I did was start to print out an equality matrix of the double array I was using. I was expecting to find a difference in the equality matrices between Linux/Solaris and Windows. There was none. This meant that two numbers which pass an equality (==) check (for the purposes of printing the matrix), later failed on a greater than or equal to (>=) check which actually affected program flow. I then created a corresponding else statement and did some more checking of the two numbers and they then pass a greater than or equal to (>=) check. So, in summary two doubles pass on ==, then fail on >=, then pass ==, >=, <= while never being modified. Does this imply compiler error? I have attached two files example.c and example.out which are just excerpts from the code and output. In example.c I have two versions of the function where the problem is happening. One is the original and one has all of the debugging fprintf statements that produced the example.out. Both versions have the same bad behavior, I just wanted to include the clean one so you can see what it is doing. The function in example.c that is failing is called combineOverlaps which just takes line sections (on a circle) and combines them if they overlap into a bigger section. A section is a simple structure with a double "from" and a double "to". The equality matrix for the failing iteration (Lines 214 to 223 from example.out) is... 0 1 2 3 ftftftft 0f=....... t.==.=... 1f.==.=... t...=.==. 2f.==.=... t...=.==. 3f...=.==. t.......= This shows that section[0]'s "to" is equal to section[1]'s "from" It actually passed twice since I'm printing the full matrix. Lines 228 to 230 of example.out are being printed from else clause (lines 129 to 136 in example.c) after it fails the >= check and shows that afterwards it passes all those other equality checks. Here is a summary of where it works and where it doesn't. OS Env GCC Options Pass/Fail Windows Msys/mingw 3.4.5 -O2 Fail Windows Cygwin 3.4.4 -mno-cygwin -02 Fail Windows Cygwin 3.4.4 -02 Fail Windows Cygwin 4.1.1 -02 Fail Windows Cygwin 3.4.4 -mno-cygwin -00 Pass Windows Cygwin 3.4.4 -00 Pass Windows Cygwin 4.1.1 -00 Pass Linux 4.1.1 -02 Pass Linux 3.4.6 -O2 Pass Solaris 4.1.1 -02 Pass It fails on Windows with any optimization in both 3.4.4 and 4.1.1, so it is not just happening on one particular version of the compiler. If a program compiled with -O0 has different output than the same program compiled with -O1 or -O2, is that defiantly a compile error? I do realize that it could be a combination of compiler optimizations along with the platform's representation of floating point numbers, but isn't that something the compiler should be aware of be careful about? Any insight is appreciated. Thanks, ~Eric
example.c
Description: example.c
example.out
Description: example.out
-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/