Casting Values

Oct 25, 2018

I have a scary Halloween story to tell you...

I was running into a bug in my new compiler where large ints where loosing precision. After tracing through my compiler's C++ code for about an hour trying to catch the spot, I came to this function:

int intConstValue() { return _type == kFloat ? _float : _int; }

It took me a bit of starring and then it hit. Something from the deep recesses of C-lore came jumping up.

Do you know the issue?

I won't keep everyone in suspense...

The both sides of trinary operator must return the same type, and in this case I was returning an INT and a FLOAT, so it cast the INT to a FLOAT before returning the value. I didn't notice it until one of my units tests sent large INT's through, larger than a FLOAT can store without loosing precision. Since the function (intConstValue) is returning an INT, I guess I assumed the it would downcast the float, but you know what they say about assuming.

I seem to recall being bitten by a similar bug 20 years ago. I guess I'm good until 2038... just in time for Unix time roll over.

Tramboi Oct 25, 2018
Maybe you should enable warnings.

Neil Oct 25, 2018
Did your compiler not give a warning? Or should I say your compiler compiler not give a warning? I guess converting built in types is always acceptable.

As a lazy C++ coder, I never remember the order of operator precedence. So when I come across an unbracketed ternary conditional A==B?C:D, I never know if it's (A==B)?C:D or A==(B?C:D). I had to look it up again.

Ron Gilbert Oct 25, 2018
I have most warning enable, or at least warning that would have caught this, and nothing.

Ron Gilbert Oct 25, 2018
Ah... you're right.  I use CMake to build xcode/VS projects and I had the warning flag that checks for int/float conversions set wrong. Oh well... Scary Halloween stories are less scary with warnings turned on.

Nor Treblig Oct 26, 2018
@Neil: The precedence of this conditional operator is very low, it's on par with assignments.
It's also right to left as you are probably used to with assignments.

IMO it is easy to remember if you think about the purpose of this operator which is all about *conditions*. E.g.
a <= b || c != d ? x : y
The whole condition is evaluated first.

Zak Phoenix McKracken Oct 27, 2018
The FDIV Pentium bug was real and scary, 20 years ago. 32.2 - 31.1 - 1.1 was not equal to zero...

Alien426 Nov 09, 2018
Where is the division (Floating-point DIVision bug) in "32.2 - 31.1 - 1.1"? You can check for that bug with "4195835 / 3145727" which should return 1.33382...
What you have shown is just a floating-point precision problem. Which still exists. Check out

Patsy J. Moore Feb 11, 2019
I hope them people will be more skeptic in things like these that's like something straight out of a sappy story.

Visit us

Mighty Pirate Apr 04, 2022
@Alien426: "What you have shown is just a floating-point precision problem. Which still exists." ... and isn't a problem.