Live data from Hacker News

Everything in C is undefined behavior

blog.habets.se

161–170 of 748 posts

Re: Everything in C is undefined behavior

#161

The 5 stages of learning about UB in C: -Denial: "I know what signed overflow does on my machine." -Anger: "This compiler is trash! why doesn't it just do what I say!?" -Bargaining: "I'm submitting this proposal to wg14 to fix C..." -Depression: "Can you rely on C code for anything?" -Acceptance: "Just dont write UB."

What stage is the "just make the compiler define the undefined" stage? Unaligned access? Packed structs. Compiler will magically generate the correct code, as if it had always known how to do it right all along! Because it has, in fact, always known how to do it right. It just didn't. Strict aliasing? Union type punning. Literally documented to work in any compiler that matters, despite the holy C standard never sayi…

> Unaligned access? Packed structs.

Packed structs are dangerous. You can do unaligned accesses through a packed type, but once you take the address of your misaligned int field, then you are back into UB territory. Very annoying in C++ when you try to pass the a misaligned field through what happens to be generic code that takes a const reference, as it will trigger a compiler warning. Unary operator+ is your friend.

Re: Everything in C is undefined behavior

#163
post #52

Earlier quoted context omitted.

Not good how? Are they TRUE? If so that's super bad.

Some of the examples are somewhat formally true in theory and bullshit in practice; some are quite hallucinatory. - Creating a potentially troublesome misaligned int pointer is a precisely localized and completely explicit user mistake, not something that just happens because it's C. - Passing signed char to character classification functions that expect an unsigned char (disguised as an int) is a very specific dumb…

Author here.

So I see your counter points are all "so just don't do that, then".

And the point of my post is that this particular "just don't do that, then" has never been achieved by humans.

If if there's no example of a program without these bugs in a language, then I do think it's fair to blame the language. A knife with 16 blades and no handle.

> Expecting C to handle "address zero" in physical memory in ways that conflict with NULL in source code denotes a complete lack of understanding of what a program is.

Like the post says, it's rare that programmers actually want a pointer to memory address zero. But in my experience most programmers who even encounter that have this "complete lack of understanding", as you put it.

Re: Everything in C is undefined behavior

#165
post #52

Earlier quoted context omitted.

Not good how? Are they TRUE? If so that's super bad.

They are true but I agree it's not a great article. C has an unending list of UB and given the title I was expecting a more comprehensive survey, but they actually just picked a few that are both fairly well known and not very interesting.

Author here.

As I stated:

> The following is not an attempt at enumerating all the UB in the world. It’s merely making the case that UB is everywhere, and if nobody can do it right, how is it even fair to blame the programmer? My point is that ALL nontrivial C/C++ code has UB.

It's about that point, not about how to avoid it. Because you can't.

Re: Everything in C is undefined behavior

#166

I have never in my 20 years of writing C heard so much about undefined behavior as I have in the past 6 months on Hacker News. It has never entered the conversation. You write the code. If it doesn't work, you debug it and apply a fix or a workaround. Why does the idea of undefined behavior in C get to the front page so consistently?

There are a lot of Rust/whatever hipsters here that have defined their whole identity around hating C and C++.

Re: Everything in C is undefined behavior

#167

The 5 stages of learning about UB in C: -Denial: "I know what signed overflow does on my machine." -Anger: "This compiler is trash! why doesn't it just do what I say!?" -Bargaining: "I'm submitting this proposal to wg14 to fix C..." -Depression: "Can you rely on C code for anything?" -Acceptance: "Just dont write UB."

In C, acceptance is "I will write UB and it will eventually lead to something bad happening"

Re: Everything in C is undefined behavior

#168

The 5 stages of learning about UB in C: -Denial: "I know what signed overflow does on my machine." -Anger: "This compiler is trash! why doesn't it just do what I say!?" -Bargaining: "I'm submitting this proposal to wg14 to fix C..." -Depression: "Can you rely on C code for anything?" -Acceptance: "Just dont write UB."

What stage is the "just make the compiler define the undefined" stage? Unaligned access? Packed structs. Compiler will magically generate the correct code, as if it had always known how to do it right all along! Because it has, in fact, always known how to do it right. It just didn't. Strict aliasing? Union type punning. Literally documented to work in any compiler that matters, despite the holy C standard never sayi…

> What stage is the "just make the compiler define the undefined" stage?

It can be left as implementation defined, which means that the compiler can't simply do arbitrary things, it needs to document what it would do.

Take, for example, signed-integer overflow: currently a compiler can simply refuse to emit the code in one spot while emitting it in another spot in the same compilation unit! Making it IB means that the compiler vendor will be forced to define what happens when a signed-integer overflows, rather than just saying, as they do now, "you cannot do that, and if you do we can ignore it, correct it, replace it or simply travel back in time and corrupt your program".

> Somehow I built an entire lisp interpreter in freestanding C that actually managed to pass UBSan just by following the above logic. I was actually surprised at first: I expected it to crash and burn, but it didn't. So if I can do it, then anyone can do it too.

Same here; I built a few non-trivial things that passed the first attempt at tooling (valgrind, UBsan with tests, fuzzing, etc) with no UB issues found.

Re: Everything in C is undefined behavior

#169

Earlier quoted context omitted.

> And before I get attacked for being a Rust shill, I meant Java :P If all you want is C but less insane then the obvious answer here is Zig.

Zig is cool, but it is not even close to being ready for prime-time. It will be pre-1.0 for a while, and major breaking changes are still happening.

Sure, maybe don't bet your entire company on mountains of Zig code just yet, but aside from the breaking changes it's been perfectly usable and suitable for every project I've ever wanted to work on.

Re: Everything in C is undefined behavior

#170

I read through this in detail... Is it just me, or are these things that are invoked by intentionally bypassing the typing? I mean, you have to go out of your way and use a cast to get the UB in the first example. For the `isxdigit` implementation, using a parameter to index into an array without a length check is pretty suspect already. I don't think any of my code actually indexes an array without checking the leng…

> I don't think this is true for C. The NULL macro is defined to be a pointer in the C standard, AFAIK. Just because comparisons with zero are allowed, does not imply that the standard implicitly promotes NULL to `int`.

Probably confusion with C++ where NULL is 0 which is a special case that can be implicitly cast to both integers and pointers, unlike non-zero constants. C doesn't need this because it doesn't require explicit casts from void pointers to others.

Post reply on HN