Community
cancel
Showing results for 
Search instead for 
Did you mean: 
mr_nuke
Beginner
73 Views

Possible compiler bug when negating unsigned size_t

I've had a problem with the following line of code:

[bash]float zVal = (float)((float)-nd/2 + 1E-5);[/bash]

nd is of type size_t, and is around0 to 200; compiled for x64, under Windows;

I was getting huge values for zVal after from that, so I checked the disassembly output to see if I can trace the issue. I noticed that it moves nd to a register, after which it uses the neg instruction on that register. With my very limited assembly knowledge, I assume that is supposed to negate the value of the register. Anyway, after the negation, the value in the register jumps to something to the order of 9E10. I figured that might be the problem, so I changed everything to:

[bash]float zVal = (float)(-((float)nd)/2 + 1E-5);[/bash]

This fixed the problem for me, but I don't understand why I encountered the problem in the first place. The exact line of code worked perfectly with the Intel compiler for over a year. I did not change compiler versions, and the othermodifications I've done to the code are unrelated to this function. Unfortunately, I can't provide a reproducible a test case.

I'm thinking it might be a compiler bug. I usedversion 11.1.051.

0 Kudos
3 Replies
Hubert_H_Intel
Employee
73 Views

Thanks for submitting this issue I can exactly reproduce with Intel C++ Compiler AND Microsoft Compiler (VS2008). So I'm not sure if this is an Intel compiler bug. But let me investigate.

Regards,

Hubert.

Hubert_H_Intel
Employee
73 Views

After having evaluated a little bit I think it should seen as a bug. Visual C++ issues the warning C4146 that makes sense; it says that using the unary minus operator with an unsigned type results in an unsigned type. That's the explanation for the compilers behavior. Intel however doesn't issue any warning, but ouptus wrong values. It should issue a warning or do the right order of type casting and negating implicitly (as gcc 4.x on Linux does). I'm going to file a defect against Intel Compiler 11.1.

Consider the following:

[cpp]#include 
unsigned nd = 100;
int main()
{
	printf ("%dn", -nd/2);
	printf ("%dn", (int)-nd/2);
	printf ("%fn", (float)-nd/2);
	return 0;
}

[/cpp]

and the output with Intel 11.1.054 is:

2147483598

-50

2147483598.000000

Press any key to continue . . .

The 2nd output is right (accidentally).So it should be avoided to use the minus unary operator directly with unsigned types; use it in front of type casted unsigned types only; for example: -(float)nd.

Does this help?

Hubert.

mr_nuke
Beginner
73 Views

Thanks for the input. I have already incorporateda similarworkaround in my code (the one in my first post).

Thanks,

Alex

Reply