CppCon 2017: Scott Schurr “Type Punning in C++17: Avoiding Pun-defined Behavior”

CppCon · 10K views · 2017 · 1:05:08

Open on YouTube

C, C++, Rust, Go & systems languagestalk

Why Stack Overflow recommends it

Stack Overflow users link it when answering questions about type punning, unions, const members and std::launder, as an authoritative explanation of what is and is not undefined behavior.

Recommended by 1 people across 1 different months, 2018 to 2021.

What it is

A CppCon 2017 talk by Scott Schurr of Ripple on type punning in C++17. It covers why people pun types, which older techniques now cause undefined behavior, and safer alternatives, along with related topics such as type conversions and std::launder().

What people said

Recommends besc · 2018-05 · Stack Overflow · on “Type punning two types from different third party libraries without union”

+1 you answered while I was typing pretty much the same thing. So let me just mention this talk from CppCon 2017, that discusses this problem and type punning in general: Scott Schurr “Type Punning in C++17: Avoiding Pun-defined Behavior” [this video]

Cites Kahler · 2018-05 · Stack Overflow · on “Swap method with const members”

tl;dr; : It's Undefined Behavior. Reference/reason: CppCon 2017: Scott Schurr “Type Punning in C++17: Avoiding Pun-defined Behavior, @24m52s +- ” [this video] My interpretation, by example: Suppose you create an object of type T , which have some const members. You can pass this object as a non-const reference to a function f(&T) that manipulates it, but you'd expect the const members to remain unalterable after the call. swap can be called in non-const references, and it can happen inside the function f , breaking the premise of const members to the caller. Every part of your code that uses swap would have to assert that the object of type T being swapped does not belong to any context where the

Cites Nicolas Holthaus · 2020-10 · Stack Overflow · on “What is the purpose of std::launder?”

In Scott Schurr's CppCon talk [this video] , he seemed to think that `std::launder` had to be used at the site of the _access_ through the `reinterpret_cast`ed pointer `p`, not at the creation, in which case trying to return a laundered pointer from a function would be futile and a Bad Idea.

Cites Phil1970 · 2021-08 · Stack Overflow · on “Packing unions/structure to avoid padding”

As far as I understand, the following code would be the most safe one. The data that specify the type is in the Initial common sequence . Thus you can access it either way (by using cda.C or cdb.C ) so it is perfect for determining the type. Then putting everything in a struct for both cases allows to ensure that each struct layout is independant (thus B can start before next 8 bytes alignment). #include <cstdint> #include <iostream> struct CDA { int16_t C; // 2 bytes int16_t D; // 2 bytes uint8_t* A; // 8 bytes }; struct CDB { int16_t C; // 2 bytes int16_t D; // 2 bytes uint8_t B[12]; // 12 bytes }; struct vdata { union union_data { CDA cda; CDB cdb; } u; }; static_assert(sizeof(uint8_t*) =