HackerTube
HomeLongsLikedHistoryWatch laterCategoriesPlaylistsSettings

CppCon 2016: Chandler Carruth “Garbage In, Garbage Out: Arguing about Undefined Behavior..."

CppCon4 HN recommenders · recommended in 4 months, 2016-2026
YouTube
94K views · 10 years ago · talk · evergreen

Chandler Carruth's CppCon 2016 talk tries to defuse the heated debate over undefined behavior in C and C++. He explains from the compiler writer's perspective why UB exists and how it enables optimization.

HN points to it whenever undefined behavior comes up, as the best explanation of the reasoning behind UB, though some dispute its framing.

C, C++, Rust, Go & systems languagesCompilers, interpreters & program analysisSoftware performance & optimization#undefinedbehavior#c++#compilers#optimization#signedoverflow#llvm

14 comments from Hacker News

@atiedebee2026 · in “What every compiler writer should know about programmers (Anton Ertl, 2015) [pdf]”

ISO C99 actually defines multiple types of deviating behaviour. What you're describing is closer to implementation-defined behaviour than anything else. The three behaviours relevant in this discussion, from section 3.4: 3.4.1 implementation-defined behavior unspecified behavior where each implementation documents how the choice is made EXAMPLE An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right. 3.4.3 undefined behavior behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). An example of undefined behavior is the behavior on integer overflow. 3.4.4 unspecified behavior behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance An example of unspecified behavior is the order in which the arguments to a function are evaluated. K&R seems to also mention "undefined" and "implementation-defined" behaviour on several occasions. It doesn't specify what is meant by undefined behav

CitesView on HN
@_gabe_2023 · in “Was Rust Worth It?”

> Thus, the compiler theoretically has the liberty to emit whatever it wants for this program. In theory, sure. In practice, what does it do? We can look and see.[0][1][2] (I don't know of any compiler that emits garbage in the example you listed). For some reason, there's this sentiment that's arisen that treats undefined behavior as some sort of bugaboo that's capable of anything and everything (including summoning nasal demons). Here's a question that I can't find an answer to. Is machine code well-defined (as in, can it contain undefined behavior)? If the answer is yes, then all Rust programs can also contain undefined behavior, because they eventually turn into machine code after all. If the answer is no, then that means once a C++ program is compiled into machine code, the executable is a well-defined program. This whole nasal demon garbage was a good hyperbole at the time to explain that, yes, undefined behavior is bad . But it's been taken to this extreme where people will use arguments like this to try and convince others that if your program has undefined behavior, then it could summon a nasal demon, because who knows what could happen. In reality, that won't happen. In reality, a signed integer overflow can result in a meaningless program, or a security vulnerability, or many other bad things, but it doesn't mean that the compiled machine code is all of a sudden inventing new instructions at random that the CPU will happily accept. It doesn't mean that your program

CitesView on HN
@moefh2023 · in “A Guide to Undefined Behavior in C and C++”

One man's "broken code produced by the compiler" is another man's "excellently optimized code by the compiler". Where to draw the line is not always clear, but here's a very clear-cut example[1] where emitting a warning would be bad. If you don't want to watch the video, it's basically this: - the code technically contains undefined behavior, but it will never be actually triggered by the program - changing the code to remove undefined behavior forces the compiler to emit terrible code Making the compiler yell at the programmer in this case would be terrible, but it's clearly a consequence of what you're asking. [1] ▶ this video

RecommendsView on HN
@xscott2023 · in “Rust fact vs. fiction: 5 Insights from Google's Rust journey in 2022”

I know you're just trashing C UB because that's fashionable, but if you really think about it there are two popular options, and you can't have both at the same time: a) UB enables valuable optimizations and is important to keep (or even add) when performance matters b) UB makes the language unusable/insecure to anyone but genius level experts and should be avoided Whenever someone (including famous/relevant people like Dennis Ritchie [0], DJ Bernstein [1], or Linus Torvalds [2]) tries to suggest cleaning up, removing, or simply not adding new cases of undefined behavior in C/C++, the optimization experts come running from the other room screaming about how important it is that "signed integer overflow must be undefined" [3] or else things will run a percent more slowly (signed overflow being just one example of UB). Also there are people who suggest adding new UB to Rust [4]. So really, either Rust is significantly slower than C because Rust doesn't have the UB you're criticizing, or C could be a cleaner language without compromising on speed and the compiler writers and standards committees are wrong. You choose, but both options are considered heresy. [0] link [1] link [2] link [3] ▶ this video [4] link

CitesView on HN
@Mathnerd3142022 · in “Falsehoods programmers believe about undefined behavior”

"goes into". ▶ this video You mean this slide of the Joker with title "Do I really look like the kind of language that would define its behavior?" As far as I can tell there is no reason LLVM couldn't compile a document like "On x86 division by zero throws a #DE exception. On ARM division by zero returns zero. On x86 shifting by more than 32 bits shifts by (cnt mod 32) bits. On ARM shifting by more than 32 bits clears all bits. [...]" that specifies all undefined behavior. The current "nasal demons" behavior is preferred in the name of performance on some SPEC benchmarks that nobody was asking for, screwing OS writers and anyone who expected sane language semantics.

CriticalView on HN
@obi1kenobi2022 · in “Falsehoods programmers believe about undefined behavior”

Suggestions like this are unfortunately quite infeasible (they fall under the hat of "define all the behaviors"), and the talk I linked in the post goes into why: ▶ this video (I'm the post's author.)

CitesView on HN
@xscott2022 · in “How I think about C99 strict aliasing rules”

It's not obvious unless you read and think about the assembly, but bonzini's point was that using a 32 bit signed int (which is not allowed to overflow) means the compiler can cleverly promote it to use register RAX as an index without any other shenanigans to deal with 32 bit overflow. RAX is a 64 bit register for integers or pointers. There are reasons why this might be advantageous over using EAX, which is the name for the low 32 bits of RAX. It's very possible that bonzini is referring to the example in the following link: ▶ this video Back to your overall point though, you're right that there's frequently an advantage to having your bulk data use smaller data types. It's better for caching and memory bandwidth, and it opens up more possibilities for parallelization with SIMD or GPU magic. However, it's really a false economy for things like loop indices. It doesn't matter if you declare your variable to be int8_t using just 1 byte, because it's probably going to tie up an entire 64 bit register anyways. There are ways to use only parts of registers, so you can pretend you have more registers, but these cause dependency stalls and are generally not good for modern processors, or at least not a win for speed. To a lesser extent, it's a false economy with floating point on the CPU too. Your 32 bit float is likely taking up an entire 128 bit (or larger) SIMD register, and the operations generally have the same latency and throughput as their 64 bit (double) equivalent. The rules

CitesView on HN
@monsecchris2022 · in “Almost Always Unsigned”

Signed integer overflow causing undefined behaviour allows the compiler to make significantly better optimisations. Here is Chandler Carruth, and clang developer, talking about it: ▶ this video

CitesView on HN
@tynorf2020 · in “Let's Destroy C”

I haven't actually watched it in a while, but are you referencing this talk by Chandler Carruth? ▶ this video

CitesView on HN
@Joky2018 · in “Trip report: Fall ISO C++ standards meeting”

Actually I discourage my colleague to use unsigned especially because they can overflow. The problem with overflow is that most of the time it is a program bug if there is an overflow that wasn't intended. Using signed arithmetic means that you can actually trap on overflow and catch these bugs (using fuzzing for instance). Chandler explained it nicely in his CPPCon 2016 talk "Garbage In, Garbage Out: Arguing about Undefined Behavior...". I encourage to watch the full talk but here is one relevant example: ▶ this video And here he mentions how Google experimented with this internally: ▶ this video

RecommendsView on HN
@lyricaljoke2018 · in “Depressing and faintly terrifying days for the C standard [pdf]”

Chandler Carruth's talk on the subject was really useful for my own understanding of the reasoning behind UB: ▶ this video

RecommendsView on HN
@kllrnohj2018 · in “A Usable C++ Dialect That Is Safe Against Memory Corruption”

The generally recommended thing for catching & fixing this is: link CppCon has also had a lot of great talks on UB and why it is what it is, such as ▶ this video

RecommendsView on HN
@crististm2017 · in “New things in clang land (5.0.0)”

▶ this video Thank you very much. Maybe the defenders of idiotic compiler behaviour can go now and hide under a rock. As for the slide at ▶ this video Correct or incorrect programs are defined in terms of the language. With an underspecified language like C you get what you deserve: -O2 being a different language than -O0 I've seen enough of this video where incorrect programs are being equaled to undefined language behavior. I'll stop looking further.

CriticalView on HN
@pjmlp2016 · in “Alpine Edge has switched to libressl”

I very much doubt it, as it goes against the C culture of micro-optimize each code line as it is written, without any feedback from a profiler because "the coder knows best!". Since I know C (1992), I have seen quite a few times people write code to go fast as they can and apply compiler optimization tricks for use cases where it hardly matters. Also many of the issues regarding UB go back to the early ANSI C days, when it was the wild west of C dialects outside UNIX and no vendor wanted to give up on their own extensions. As for C and C++ compiler writers view on UB: ▶ this video

CitesView on HN
CppCon 2015: Chandler Carruth "Tuning C++: Benchmarks, and CPUs, and Compilers! Oh My!"1:29:54

CppCon 2015: Chandler Carruth "Tuning C++: Benchmarks, and CPUs, and Compilers! Oh My!"

CppCon
188K views • 11 years ago
2013 Keynote: Chandler Carruth: Optimizing the Emergent Structures of C++1:33:02

2013 Keynote: Chandler Carruth: Optimizing the Emergent Structures of C++

CppNow
34K views • 13 years ago
CppCon 2016: Herb Sutter “Leak-Freedom in C++... By Default.”1:39:25

CppCon 2016: Herb Sutter “Leak-Freedom in C++... By Default.”

CppCon
149K views • 10 years ago
CppCon 2016: Chandler Carruth “High Performance Code 201: Hybrid Data Structures"55:49

CppCon 2016: Chandler Carruth “High Performance Code 201: Hybrid Data Structures"

CppCon
119K views • 10 years ago
CppCon 2014: Chandler Carruth "Efficiency with Algorithms, Performance with Data Structures"1:13:41

CppCon 2014: Chandler Carruth "Efficiency with Algorithms, Performance with Data Structures"

CppCon
235K views • 12 years ago
CppCon 2017: Chandler Carruth “Going Nowhere Faster”1:00:58

CppCon 2017: Chandler Carruth “Going Nowhere Faster”

CppCon
113K views • 9 years ago
CppCon 2019: Chandler Carruth “There Are No Zero-cost Abstractions”59:53

CppCon 2019: Chandler Carruth “There Are No Zero-cost Abstractions”

CppCon
147K views • 7 years ago
CppCon 2015: Herb Sutter "Writing Good C++14... By Default"1:29:06

CppCon 2015: Herb Sutter "Writing Good C++14... By Default"

CppCon
193K views • 11 years ago
CppCon 2016: Dan Saks “extern c: Talking to C Programmers about C++”1:36:27

CppCon 2016: Dan Saks “extern c: Talking to C Programmers about C++”

CppCon
175K views • 10 years ago
CppCon 2017: Matt Godbolt “What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid”1:15:46

CppCon 2017: Matt Godbolt “What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid”

CppCon
178K views • 9 years ago
CppCon 2018: G. Nishanov “Nano-coroutines to the Rescue! (Using Coroutines TS, of Course)”1:04:26

CppCon 2018: G. Nishanov “Nano-coroutines to the Rescue! (Using Coroutines TS, of Course)”

CppCon
40K views • 8 years ago
CppCon 2017: Fedor Pikus “C++ atomics, from basic to advanced.  What do they really do?”1:14:22

CppCon 2017: Fedor Pikus “C++ atomics, from basic to advanced. What do they really do?”

CppCon
288K views • 9 years ago
CppCon 2019: Matt Godbolt “Path Tracing Three Ways: A Study of C++ Style”55:42

CppCon 2019: Matt Godbolt “Path Tracing Three Ways: A Study of C++ Style”

CppCon
77K views • 7 years ago
CppCon 2017: Louis Brandy “Curiously Recurring C++ Bugs at Facebook”52:01

CppCon 2017: Louis Brandy “Curiously Recurring C++ Bugs at Facebook”

CppCon
158K views • 9 years ago
CppCon 2016: Jason Turner “Rich Code for Tiny Computers: A Simple Commodore 64 Game in C++17”1:19:52

CppCon 2016: Jason Turner “Rich Code for Tiny Computers: A Simple Commodore 64 Game in C++17”

CppCon
264K views • 10 years ago
C++ Exceptions for Smaller Firmware - Khalil Estell - CppCon 20241:24:36

C++ Exceptions for Smaller Firmware - Khalil Estell - CppCon 2024

CppCon
23K views • 1 year ago
CppCon 2014: Jeff Preshing "How Ubisoft Develops Games for Multicore - Before and After C++11"1:04:33

CppCon 2014: Jeff Preshing "How Ubisoft Develops Games for Multicore - Before and After C++11"

CppCon
53K views • 12 years ago
CppCon 2017: Herb Sutter “Meta: Thoughts on generative C++”1:47:45

CppCon 2017: Herb Sutter “Meta: Thoughts on generative C++”

CppCon
105K views • 9 years ago
CppCon 2014: Mike Acton "Data-Oriented Design and C++"1:27:46

CppCon 2014: Mike Acton "Data-Oriented Design and C++"

CppCon
862K views • 12 years ago
Modernizing Compiler Design for Carbon Toolchain - Chandler Carruth - CppNow 20231:35:12

Modernizing Compiler Design for Carbon Toolchain - Chandler Carruth - CppNow 2023

CppNow
71K views • 3 years ago