CppCon 2017: Piotr Padlewski “Undefined Behaviour is awesome!”

CppCon · 37K views · 2017 · 53:59

Open on YouTube

C, C++, Rust, Go & systems languagesCompilers, interpreters & program analysisSoftware performance & optimizationtalk

Why Stack Overflow recommends it

Stack Overflow users link it when explaining why undefined behaviour is dangerous, how compilers reason about it, and why UB can have surprising effects before and after the faulty line.

Recommended by 5 people across 5 different months, 2018 to 2020.

What it is

A CppCon 2017 talk by Piotr Padlewski on C++ undefined behaviour and why compilers exploit it. It covers the as-if rule, translation unit limits, optimizations driven by UB, and how UB can remove code that never even runs.

What people said

Recommends Flamefire · 2018-02 · Stack Overflow · on “Undefined behaviour on reinitializing object via placement new on this pointer”

I saw a presentation on cppcon of Piotr Padlewski [this video] saying that the following is undefined behaviour: int test(Base* a){ int sum = 0; sum += a->foo(); sum += a->foo(); return sum; } int Base::foo(){ new (this) Derived; return 1; } Note: Assume sizeof(Base) == sizeof(Derived) and foo is virtual. Obviously this is bad, but I'm interested in WHY it is UB. I do understand the UB on accessing a realloc ed pointer but he says, that this is the same. Related questions: Is `new (this) MyClass();` undefined behaviour after directly calling the destructor? [LINK] where it says "ok if no exceptions" Is it valid to directly call a (virtual) destructor? [LINK] Where it says new (this) MyClass(); re

Recommends Arne Vogel · 2018-06 · Stack Overflow · on “Which integer operations are unsafe?”

To summarize the previous observations, there are exactly two possible causes of undefined behavior relating to your list of operations: division by zero overflow (whether negative or positive) – your example of negating std::numeric_limits<int64_t>::min() – whether by division or otherwise – is just an example of that. Only the arithmetic operators (the first five from your list) are affected by either of these issues, all others have well-defined behavior for all inputs. What I want to do is expand on the dangers of integer overflow and undefined behavior. First, I'd highly recommend you to watch Undefined Behavior is Awesome [this video] by Piotr Padlewski, and the Garbage In, Garbage Out [LIN

Recommends einpoklum · 2018-10 · Stack Overflow · on “Calling `delete` on an object owned by a `unique_ptr` using another pointer”

@Yakk-AdamNevraumont: But that's kind of cheating. I mean, a filesystem API's _defined_ behavior can involve deleting things. There's this CppCon 2017 talk, Undefined behavior is awesome [this video] where Piotr Padlewski explains how to maybe make that happen really inadvertantly and unexpectedly.

Recommends cdhowie · 2020-08 · Stack Overflow · on “if(x % y == 0) is causing my program to not output anything?”

@noobCodeKid We have all been there, and even seasoned C++ developers will cause UB from time to time. It can be a _bear_ to track down, too. Check out Piotr Padlewski's talk on UB [this video] -- it demonstrates some _crazy_ things that compilers will do when they encounter UB. While they make sense, it can make debugging the problem very difficult. (Why was my complicated function reduced to a single instruction!?)

Recommends Michael Schmitt · 2020-09 · Stack Overflow · on “Ternary with uninitialized bool leads to buffer overflow on macOS”

The following code leads to very strange behavior. #include <iostream> #include <string> class A { std::string x = ""; std::string y = "a"; bool b; // Uninitialized! public: void test() { std::cout << y + (b ? "b" : "") << std::endl; } }; int main(int argc, const char * argv[]) { A a; a.test(); return 0; } Instead of outputting either "ab" or just "a" it actually echos: ab $\321XQ\300\<\246 \\300\324< \340\353 =X | After finding out that the reason for it was the uninitialized variable b I am still curious to why this happens (and only in release build on clang for macos). Edit: Simplified the example further. If I remove A::x , it echos a . If I change it to y + (b ? "b" : "c") it echos ab

Cites Arne Vogel · 2018-02 · Stack Overflow · on “If a part of the program exhibits undefined behavior, would it affect the remainder of the program?”

This is not a paradox in many cases, e.g. when code does `++i; ++*p;`, and `p` happens to be nullptr. Assuming normal integers, a compiler is free to reorder these, for example, so the program might segfault before incrementing `i`. When a segfault handler is installed, or `i` resides in shared memory, the difference might be observable. Also, a compiler may eliminate both succeeding and *preceding* statements from a function or block that provably contains an unconditional UB, and they actually do this [this video] .

Cites Arne Vogel · 2018-11 · Stack Overflow · on “Rationale of restrictive rules for extract and re-insert with map”

I'm just following up on Kerrek SB's answer in the hope to explain the issue in more detail (and hence a bit more convincingly). The adopted revision 3 of the paper in question (P0083R3) [LINK] mentions the std::pair<const Key, Mapped> vs std::pair<Key, Mapped> conundrum, and that "The conversion between these can be effected safely using a technique similar to that used by std::launder on extraction and reinsertion." IOW, extraction and reinsertion are safe from optimizations related to type punning by invoking "implementation 'magic'" (this is the explicit wording in the paper) to resolve any possible aliasing problems within the container code itself, and insofar as user code abides by th

Cites cigien · 2020-05 · Stack Overflow · on “Is UB in unevaluated context (e.g. requires-expressions) still UB?”

@cdhowie Here's the example [this video] I was thinking of. There *isn't* any path that takes the address of a function, but the UB arises from the fact that the compiler assumes that there *must* be a path. I'm not sure if this actually answers your question about "never even called", but it's the example I was referring to.