Lightning Talk: Un-Undefining Undefined Behavior in C++ - Jefferson Carpenter - CppCon 2023

Sdílet
Vložit
  • čas přidán 10. 04. 2024
  • cppcon.org/
    ---
    Lightning Talk: Un-Undefining Undefined Behavior in C++ - Jefferson Carpenter - CppCon 2023
    github.com/CppCon/CppCon2023
    Interpreting the C++ abstract machine in the context of the real machine that it runs on. If your program contains UB, the compiler is allowed to emit any code whatsoever, and may optimize out any code paths leading to UB. But what if you made it so the compiler had no way to tell that the behavior was undefined? Then it would have to generate code such that, if the behavior was defined, the program would run correctly. Then you can write all the UB you want! In this undefined talk, I give a couple examples of UUB (un-undefined behavior).
    ---
    Jefferson Carpenter
    I spent my early life as a baby, but soon grew into a child. By college I had already graduated from high school, and now I'm extant.
    ---
    Videos Filmed & Edited by Bash Films: www.BashFilms.com
    CZcams Channel Managed by Digital Medium Ltd: events.digital-medium.co.uk
    ---
    Registration for CppCon: cppcon.org/registration/
    #cppcon #cppprogramming #cpp
  • Věda a technologie

Komentáře • 18

  • @12affes
    @12affes Před měsícem +2

    This is cursed, love it!

  • @chriselrod3884
    @chriselrod3884 Před měsícem +1

    I know these were a joke, but I'd just use `std::bit_cast` in C++20 or newer to cast between `Foo` and `Bar`, or do `rsqrt` (you also shouldn't use that rsqrt instruction on most CPUs, e.g. on x64 vrsqrt14ps is just better if you have AVX512, or vrsqrtss otherwise).
    For signed integer overflow, can `std::bit_cast(i)`, and then similarly bitcast back to signed.
    I much prefer signed overflow being UB, because that lets me actually check for it in debug mode with UBsan.
    The code I wrote's behavior is undefined in that case, regardless of whether the compiler thinks it is defined or not, so let it help me find that bug.
    In release mode, I've also seen cases where it did make a real difference to the quality of the assembly generated. If a signed integer overflows, it is a bug.

  • @ron3060
    @ron3060 Před měsícem +1

    very good and intersting talk that should have been extended to little more than 5 min

  • @marcoradovancovici1312
    @marcoradovancovici1312 Před měsícem

    Nice talk!

  • @justinlink1616
    @justinlink1616 Před měsícem

    This was so ridiculous ... but yet still awesome.

  • @andrewnoyes9932
    @andrewnoyes9932 Před měsícem +1

    These all still invoke undefined behavior. It's just that they've found a way to get a particular compiler, on particular hardware, at a particular time, do generate code which behaves an intended way in spite of invoking undefined behavior. Also undefined behavior is not anything left unspecified in the standard. Scenarios which invoke undefined behavior are explicitly described in the standard.
    The helpful way to think about UB is that implementation is allowed to assume that it never happens. Compiler's aren't looking for an excuse to reformat your hard drive - they're mostly just removing dead code (dead assuming UB is not invoked).

    • @philnik777
      @philnik777 Před měsícem

      I think you might take this a bit too seriously. Also, UB isn't necessarily called out. UB is anything which the standard imposes no requirements on, including things the standard is silent on. Ironically this is explicitly stated in [defns.undefined].

  • @GreenJalapenjo
    @GreenJalapenjo Před měsícem +1

    This is a fun talk! I kinda wish it wasn't called "un-undefining UB" though, it's still UB even when the different parts are in different libraries etc. "Getting away with undefined behaviour" maybe?

    • @yokozombie
      @yokozombie Před měsícem

      smearing your objects with UB

  • @Dino-Kupinic
    @Dino-Kupinic Před měsícem

    why no mono spaced font for the code

  • @jamesburgess9101
    @jamesburgess9101 Před měsícem

    Very funny, excellent presentation! Do you also have a real answer for float bit pattern manipulation, maybe link that too?

    • @dimula73
      @dimula73 Před měsícem

      As far as I remember the expected approach it to use std::memcpy on those pointers, though i haven't checked that myself.

    • @digama0
      @digama0 Před 23 dny

      You can also use std::bit_cast since C++20 IIRC

  • @ABaumstumpf
    @ABaumstumpf Před měsícem

    It would be great if we could actually just define the behaviour. Let ME decide what i want.
    I say that signed integer overflow IS defined cause i know the target architecture. So no - in that case the standard saying it is "undefined" should have absolutely NO impact as it is proven wrong for that situation, yet they made the language so that even if i know that i can not get a program to do so except if i change the compiler to ignore the standard.

    • @m13253
      @m13253 Před měsícem +1

      Defining them comes with a performance cost.
      For example, during loop analysis, assuming a signed integer never overflows can help the compiler determine the boundary of loop and emit efficient SIMD code.

  • @hohohaha5297
    @hohohaha5297 Před měsícem

    Isn't this just an instruction how to fool the compiler? Namely the one piece of code that's trying to help you not write code like that?

  • @yrucoding
    @yrucoding Před měsícem

    😂😂😂

  • @N....
    @N.... Před měsícem

    This lightning talk is hilarious, but now I wonder if std::bit_cast would work for that inverse square root algorithm... though, IIRC, there's already a single x86 instruction for the algorithm, so it's more relevant for other architectures like ARM64