Thread: difference between ++*x and x*++

  1. #16
    Registered User
    Join Date
    May 2019
    Posts
    214
    @I C Everything,

    You've already received two wise replies.

    I'd like to point out that this:

    you wrote about optimization....like you mean full optimize arent foolproof,it suddenly breaks code....
    is a form of correlation reasoning error. As pointed out by laserlight and click_here, it isn't the optimizer itself, but the code applied to it - meaning the reverse is not true - the optimizer does not suddenly break your code unless the code is flawed to begin with.

    The reverse logic of this is really that where code is fragile in this respect (based on undefined behavior), various settings of the compiler cause that undefined behavior to actualize in different ways.

    I risk changing the subject, but I defend this on the basis that it exposes just what we rely upon being defined behavior, and how that "breaks" our code.

    I have a long running feud with this bit of nonsense:

    if ( a != a ) ....
    This is the identity law expressed as a test. There SHOULD not ever be a case where a is not equal to a. It is a fundamental property of identity, meaning identity is stable over time - that short time between the moment "a" is observed and then tested to see if it actually equals itself.

    Why even write this nonsense? It SHOULD be recognized by all compilers as false at all times (and optimizers will routinely ignore the test and substitute "false" here, or true for "a == a" ).

    Well, there's an exception to that fact.

    It just so happens that when "a" is a floating point type, comparing any floating point type that is in the "IEEE" format, where one or both floats are NAN (Not a Number), then it is defined by that specification that two NAN's will never equal each other. This is an arbitrary choice made with respect to floating point numbers where errors have happened. You get a NAN by providing a negative number to the sqrt function, or division by zero (if you survive the processor exception).

    Well, sometimes we must test to see if a floating point value is a NAN (or perhaps we look to see if it is INF, infinity + or -).

    The PROPER way in modern work is to use a standard library function like "isnan" to see. THAT code will look at the format of a floating point value to test the bits for the pattern which is defined to be a NAN. It's quick, it's reliable and it's standard.

    However, there are people who insist that "a != a" (or "a == a" ) is a valid test for NAN. Indeed, if you ask the CPU to compare any NAN to itself, it will respond that they are not equal to each other (if the CPU "knows" IEEE).

    This bit of nonsense CAN tell you that "a" is a NAN when "a != a" is true (or "a == a" is false).

    There's a problem.

    That only works under certain compiler configurations.

    Most of the time we use default settings. "a != a" works under those conditions.

    One, little, seemingly innocent change....and this test no longer works. That's because the compiler honors "strict" conformance to "IEEE" math specifications under most default configurations, but if you select "fast" math, instead, all of the IEEE math stuff still works ok, just a tad relaxed on some minor rounding rules and.....of course....optimizing this expression "a != a". When strict compliance is relaxed, the compiler recognizes this as an identity expression - and never even examines "a" to see if the self-equality is false - it just optimizes this test away and assumes it is always false (like LOGIC would tell us).

    There are code examples that "rely" on this "a != a" test to show a float is a NAN. It works, until a slight change makes it evaporate silently without any warning from the compiler.

    There is a long list of references stating that "a != a" is a way to test for NAN, without ever clarifying what compiler configuration is required.

    Indeed, the C language doesn't say this works to test for NAN. It is the IEEE specification that does that, and so only if the compiler is configured for strict IEEE compliance will the optimizer even consider actually testing "a" to see if "a != a" happens to return true. The compiler must emit code to get the CPU to test this to even know.

    Now, in this case, we're not breaking code by C specification. We're breaking code that "expects" strict IEEE specifications.

    Some programmers have gone so far as to lecture that we should not be setting the compiler to a configuration that breaks our code, with respect to this idiom "a != a". I find that....disturbing.

  2. #17
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Niccolo - That sounds like a terrible bug to find.

    After a quick google I can see why you are frustrated

  3. #18
    Registered User
    Join Date
    May 2019
    Posts
    214
    @Click_here, thank you a thousand times - in some of those discussions I feel like I'm hitting my head against a brick wall.

    It gets even worse. The "defenders" go on, and on, without stopping to think that checking for the bits (a few bit mask operations) is quick, but this thing (the idiom in the presence of a NAN in the cpu register) fires a processor exception. That exception is then handled by microcode. The result is that it takes longer than a cache miss - some 25+ ticks go by because of the exception (which is silent to the program). Bit fiddling would be maybe 8 ticks at most.

    Strange, too, that there must be at least one runtime library implementing isnan that uses this idiom instead of testing the bits, because on most compilers the standard isnan function works no matter what compiler configurations are set, except one (I think it's GNU of a certain age).

    I'm generally an easy going guy, but that c**p gets my blood boiling, and I hardly ever even test for NAN (I don't divide by zero, I don't try to sqrt a negative number....you know?).

  4. #19
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    All good Niccolo - You kind of remind me of a user that used to be on here, Nominal_animal.

    They used to give amazing detailed answers and had a nack for understanding problems.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Difference??
    By aintgotnoname in forum C Programming
    Replies: 2
    Last Post: 11-25-2013, 10:54 PM
  2. What's the difference?
    By cuicle in forum C Programming
    Replies: 2
    Last Post: 09-30-2011, 01:41 PM
  3. Difference between C and C++
    By musicman in forum C Programming
    Replies: 8
    Last Post: 06-09-2011, 10:11 PM
  4. Is there a difference between...
    By jimbo_1 in forum C Programming
    Replies: 6
    Last Post: 03-25-2011, 05:29 PM
  5. Difference b/w int* p1 and int *p1
    By pprabhakar in forum C Programming
    Replies: 16
    Last Post: 08-21-2005, 05:27 AM

Tags for this Thread