Code crashes at runtime - is this valid c++

  • Thread starter chrisstankevitz
  • Start date
C

chrisstankevitz

Compile with:
g++ crash.cpp -O2

Crashes on:
g++ (Gentoo 4.3.2 p1.1) 4.3.2
g++ (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)
g++ (ubuntu current stable)

Steps to reproduce:
1. Make a file crash.cpp (contents below)
2. g++ crash.cpp -O2
3. ./a.out
Floating point exception

Source:

#include <iostream>
#include <fenv.h>

float g(const float& x)
{
float y = x;
if(y == 0.0f)
{
y=1.0f;
}
return x/y;
}

void f(const float &z)
{
if (z > 0.0f)
{
float Unit2 = g(z);

std::cout << Unit2;
}
}

int main()
{
feenableexcept(FE_INVALID);

float a = 130.0f;
f(a);

return 0;
}
 
R

Rolf Magnus

Compile with:
g++ crash.cpp -O2

Crashes on:
g++ (Gentoo 4.3.2 p1.1) 4.3.2
g++ (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)
g++ (ubuntu current stable)

Doesn't crash here with:
g++ (Ubuntu 4.3.2-1ubuntu11) 4.3.2

Steps to reproduce:
1. Make a file crash.cpp (contents below)
2. g++ crash.cpp -O2
3. ./a.out
Floating point exception

It prints '1' here, which is what I would have expected.
 
P

Pawel Dziepak

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Rolf said:
Doesn't crash here with:
g++ (Ubuntu 4.3.2-1ubuntu11) 4.3.2

On gcc version 4.3.0 20080428 (Red Hat 4.3.0-8) got from Fedora 9
repositories also works correctly.

Pawel Dziepak
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkkTV2UACgkQPFW+cUiIHNqDKwCfcaNU4o20I8NJ7qAhH/6ayGfH
73EAoKnn9MmwvG54pHzEwf0mFY1j9NRu
=r1+s
-----END PGP SIGNATURE-----
 
S

Salt_Peter

Compile with:
g++ crash.cpp -O2

Crashes on:
g++ (Gentoo 4.3.2 p1.1) 4.3.2
g++ (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)
g++ (ubuntu current stable)

Steps to reproduce:
1. Make a file crash.cpp (contents below)
2. g++ crash.cpp -O2
3. ./a.out
Floating point exception

Source:

#include <iostream>
#include <fenv.h>

float g(const float& x)
{
float y = x;
if(y == 0.0f)

Never compare 2 floats for equality.
Apart from the fact that its an intensive operation for a cpu,
the following is expected...

#include <iostream>

int main()
{
float fa(0.0f);
float fb(0.0f);

if( fa == fb)
std::cout << "not equal\n";
else
std::cout << "equal\n";

std::cout << "Press ENTER to EXIT.\n";
std::cin.get();
}

/*
not equal
*/
{
y=1.0f;
}
return x/y;

}

void f(const float &z)
{
if (z > 0.0f)

z might be 0.0000000001f
 
C

chrisstankevitz

It prints '1' here, which is what I would have expected.

Peter,

Thanks that's good that it works for you. Did you use the -O2
option? On three distributions it does not work for me: gentoo,
fedora, and ubuntu.

Chris
 
C

chrisstankevitz

Crashes on:
g++ (Gentoo 4.3.2 p1.1) 4.3.2
g++ (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)
g++ (Ubuntu 4.3.2-1ubuntu11) 4.3.2 (my machine, but maybe not Rolf's)

Does not crash on:
g++-4.1.2 (GCC) 4.1.2 (Gentoo 4.1.2 p1.1)

I'm trying SVN version of g++ now.

Chris

PS: Rolf, sorry for calling you Peter earlier.
 
A

Andrey Tarasevich

Salt_Peter said:
Never compare 2 floats for equality.

This is a popular _fake_ rule. There are contexts where it is perfectly
valid to compare machine floats for equality. You just need to
understand what you are doing.
Apart from the fact that its an intensive operation for a cpu,
the following is expected...

#include <iostream>

int main()
{
float fa(0.0f);
float fb(0.0f);

if( fa == fb)
std::cout << "not equal\n";
else
std::cout << "equal\n";

std::cout << "Press ENTER to EXIT.\n";
std::cin.get();
}

/*
not equal
*/


No, this is not expected. Quite the opposite, the implementation that
produces this result is clearly broken.
 
J

James Kanze

I can't reproduce it on any of the systems I have available
here. (Solaris on Sparc, with g++ 4.1.0 or Sun CC 5.8; Linux
2.6.9 on Intel, with g++ 4.1.0, and Windows XP with VC++ 14).
Of course, for all but Linux, I had to modify the code to get it
to compile.

This header is not standard C++, and is only available if you
have C99 as well. (Which means that I would normally expect it
pretty much everywhere---but my expectations are disappointed;
it's present neither under Solaris nor Windows.)
Never compare 2 floats for equality.

Which is very poor advice. In this particular case, comparison
for equality is exactly what he wants.
Apart from the fact that its an intensive operation for a cpu,

Since when? It's as fast as any other comparison, integral or
floating point, on the machines available to me.
the following is expected...
#include <iostream>
int main()
{
float fa(0.0f);
float fb(0.0f);
if( fa == fb)
std::cout << "not equal\n";
else
std::cout << "equal\n";
std::cout << "Press ENTER to EXIT.\n";
std::cin.get();
}
/*
not equal
*/

Are you kidding? Any compiler which outputs "not equal" with
that program is seriously broken.
z might be 0.0000000001f

And z might be -0.000000001f. Or 1e30. Or anything else. The
whole point is that he doesn't know, and that he doesn't want to
divide by zero. The only correct test is thus:

if ( z != 0.0F )

Anything else is a programming error, and shows a complete lack
of understanding of how machine floating point works.

Note that in his actual code, the function is only called with z
equal 130.0. Which can't be 0.0, anyway you cut it, and will
always be greater than 0.0. (For that matter, I don't know of a
machine where it won't be represented exactly.)

For the original poster: does adding the option -ffloat-store
have any effect? G++ isn't fully standards compliant without
it. Not that I think that it could affect your program; all of
the values you use are exactly representable. (It could affect
the program if the value you are comparing with 0.0 is the
result of an expression, and in some strange way, the compiler
picks it up from a register in the comparison, but reloads it
from memory for the division. And the actual real intermediate
results were smaller than 1E-38.) For Intel processors, g++
also accepts -mpc64 and -mpc32, which cause all intermediate
values to be rounded to 64 or 32 bits---this will not only
eliminate excess precision in the intermediate values, but may
also run a little bit faster (particularly on older hardware.
 
T

Thomas J. Gritzan

[about comparing floating point numbers]


"==": not equal,
"!=": equal?

I'll case that as typing error. ;-)
Are you kidding? Any compiler which outputs "not equal" with
that program is seriously broken.

I disagree. Any compiler outputting "equal" with this program is broken.

But trying to prove something with a wrong program is broken, too.
 
R

Rolf Magnus

Crashes on:
g++ (Gentoo 4.3.2 p1.1) 4.3.2
g++ (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)
g++ (Ubuntu 4.3.2-1ubuntu11) 4.3.2 (my machine, but maybe not Rolf's)

I tried it with -O2. No crash with the very same compiler version.

PS: Rolf, sorry for calling you Peter earlier.

No problem. I think I'll live ;-)
 
C

chrisstankevitz

I tried it with -O2. No crash with the very same compiler version.

Looks like it's a problem with 64 bit only. I also don't have a
problem on 32 bit.

Rolf, are you running 32 or 64 bit?

I filed a bug and it was closed fixed in 4.3.3

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top