Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • In C/C++ just adding two integers can lead to undefined behaviour. Your expectations are too high.
  • Even worse, checking for overflow before casting can be tricky: https://stackoverflow.com/questions/526070/handling-overflow...

    It's sad that comparison operators in C/C++ can lead to UB. Comparing unsigned to signed ints or comparing floats to ints is something the compiler could make work reliably at very little extra cost.

  • Hopefully this will be part of UB fixes for C++29, where plenty of UB is being redefined as erroneous behaviour instead.
  • Today people think that Java's main feature was OOP, but its main selling point was "no undefined behavior" (e.g. "int" means 32-bit signed integer with overflows, on any platform, no exceptions). Today it sounds normal, but back in the day that was what made Java popular.
  • Sounds like the standard should say that it results in an implementation-defined value (or wording to that effect). Saying it's UB gives the compilers way too much leeway.
  • > The correct fix is to bounds check before casting.

    This will do wonders for speed. Actually explicitly using the safe isntr might be better. Something like this will happily compile to a single instr and cause you no grief even if the compiler had it out for you with UB. These instrs all clearly define outputs for all inputs (note that said outputs may not match across architectures)

       static inline __attribute__((always_inline)) int f2i(float myFloat) {
          int myInt;
    
          #if defined(__arm__)
             asm("VCVT.S32.F32 %0, %1":"=r"(myInt), "t"(myFloat));
          #elif defined (__aarch64__)
             asm("FCVTZS %0, %1":"=r"(myInt), "w"(myFloat));
          #elif defined (__x86_64__)
             asm("CVTTSS2SI %0, %1":"=r"(myInt), "x"(myFloat));
          #else
             #if 0 // be boring
                if (myFloat <= TOO_SMALL_FLOAT || myFloat => TOO_BIG_FLOAT)
                   abort();
             #else
                #warning "Embrace the UB"
             #endif
             myInt = (int)myFloat;
          #endif
          return myInt;
       }
  • Herb Sutter's comment on why it's ok is confusing to me:

    > Regarding the use of UB internally: It's okay and if anyone is worried about it the use of UB is benign on the platforms we target (e.g., they don't involve hitting any hardware trap representations for these types)

    Isn't the outcome of the UB (ie. whether it will "rm -rf /" or something else) dependent on both the target and the compiler? And the compiler (or future compiler) could plausibly make the assumption that the narrowing to an unrepresentable value will never occur and change behaviour because of it?

Explore Birbla archives