Live data from Hacker News

Everything in C is undefined behavior

blog.habets.se

91–100 of 748 posts

Re: Everything in C is undefined behavior

#91
post #52

As much as I agree with the intro, these examples aren't good and the overall article is just a veil for pushing LLM coding.

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.

Re: Everything in C is undefined behavior

#92
post #83

most languages don't even HAVE a specification so in most languages literally EVERYTHING everything is undefined behavior

UB doesn't mean that it is not specified (actually it is often very well specified), it means that compilers can and do assume that such code patterns will not be present. Those cases may not be considered and can lead to unexpected behaviour.

Additionally, some (most?) UB is intentionally UB so that optimisers are free to do fancy tricks assuming that certain cases will never happen. Indeed, this is required for high performance. If they do happen, again, it can lead to unexpected behaviour.

PS: Most languages that don't have a specification declare their primary implementation to be specification-as-code. Rust is an example of that, and it does still have UB: the cases that the compiler assumes will not happen.

Re: Everything in C is undefined behavior

#94
post #2

I stoped reading about here: > bool parse_packet(const uint8_t* bytes) { > const int* magic_intp = (const int*)bytes; // UB! Author, if you are reading this, please cite the spec section explaining that this is UB. Dereferencing the produced pointer may be UB, but casting itself is not, since uint8_t is ~ char and char* can be cast to and from any type. you might try to argue that uint8_t is not necessarily char, and…

The issue is not type punning (itself a very common source of UB), but the fact that the `bytes` pointer might not be int-aligned. The spec is clear that the creation (not just the dereferencing) of an unaligned pointer is UB, see 6.3.2.3 paragraph 7 of the C11 (draft) spec. Of course, this exchange just demonstrates the larger point, that even a world-class expert in low level programming can easily make mistakes in…

> Of course, this exchange just demonstrates the larger point, that even a world-class expert in low level programming can easily make mistakes in spotting potential UB.

A "world-class expert in low level programming" knows that unaligned memory accesses are no problem anymore on most modern CPUs, and that this particular UB in the C standard is bogus and needs to fixed ;)

Re: Everything in C is undefined behavior

#95
post #72

Earlier quoted context omitted.

> LLM generated code will eventually contain UB. Yes. Even in languages other than C (i.e. you will get behaviour that nothing in the input specified). When LLMs generate code, all languages have UB.

That's a bit silly. UB means literally no restrictions. So if you standard says 'you have to crash with an error message' that's already no longer UB.

> So if you standard says 'you have to crash with an error message' that's already no longer UB.

Sure. For crashes. But when you instruct an LLM to do something, the output is probablistic, so you may get behviour that is unexpected and/or unwanted.

Like storing security tokens in code. Or nuking the production database.

Re: Everything in C is undefined behavior

#96

Earlier quoted context omitted.

> The examples are unequivocally UB. Full stop. Tbh, already the first example (unaligned pointer access) is bogus and the C standard should be fixed (in the end the list of UB in the C standard is entirely "made up" and should be adapted to modern hardware, a lot of UB was important 30 years ago to allow optimizations on ancient CPUs, but a lot of those hardware restrictions are long gone). In the end it's the CPU a…

There are still modern CPUs that don't support misaligned access. It would be insane for C to mandate that misaligned accesses are supported. However I do agree that just saying "the behaviour is undefined" is an unhelpful cop-out. They could easily say something like "non-atomic misaligned accesses either succeed or trap" or something like that. > In the end it's the CPU and not the compiler which decides whether an…

On hardware that doesn't support it, misaligned loads could be compiled to multiple loads and shifts. Probably not great for performance, and it doesn't work if you need it to be atomic, but it isn't impossible.

Re: Everything in C is undefined behavior

#97

Earlier quoted context omitted.

The examples are unequivocally UB. Full stop. How to think of this properly is that when you have UB, you are no longer under the auspices of a language standard. Things may work fine for a time, indefinitely even. But what happens instead is you unknowingly become subject to whimsies of your toolchain (swap/upgrade compilers), architecture, or runtime (libc version differences). You end up building a foundation on q…

> The examples are unequivocally UB. Full stop. Tbh, already the first example (unaligned pointer access) is bogus and the C standard should be fixed (in the end the list of UB in the C standard is entirely "made up" and should be adapted to modern hardware, a lot of UB was important 30 years ago to allow optimizations on ancient CPUs, but a lot of those hardware restrictions are long gone). In the end it's the CPU a…

I agree. I meant to elaborate more on how to think of UB.

For most C software on x86_64, UB is "fine" with very strong bunny ears. But it is preferable for one to, shall we say, write UB intentionally rather than accidentally and unknowingly. Having an awareness of all the minefields lends for more respect for the dangers of C code, it makes one question literally everything, and that would hopefully result in more correct code, more often.

On that note, on some RISC-V cores unaligned access can turn a single load into hundreds of instructions.

I think the problem is just that C is under specified for what we expect a language to provide in the modern age. It is still a great language, but the edges are sharp.

Re: Everything in C is undefined behavior

#98
post #77
post #69

Earlier quoted context omitted.

That better be marked "historical". At least, Lemire says: On recent Intel and 64-bit ARM processors, data alignment does not make processing a lot faster. It is a micro-optimization. Data alignment for speed is a myth. // https://lemire.me/blog/2012/05/31/data-alignment-for-speed-m... (while in the olden days, a program may crash on unaligned access, esp on RISC)

Don't mix up what processors do with what the C standard allows you to get away with.

...and don't mix up the C standard with what actually existing compilers allow you to get away with ;) In the end the standard is merely a set of guidelines. What matters is how compiler toolchains behave in the real word, and breaking code which does unaligned memory accesses by 'UB exploitation' would be quite insane.

Re: Everything in C is undefined behavior

#99

Earlier quoted context omitted.

I'm not assuming anything about bit representations. In this case, the spec language is quite clear and unambiguous. 6.3.2.3 paragraph 7: A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned[footnote 68]) for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the orig…

I do not see there a promise that the cast will produce an invalid pointer, nor anything prohibiting the compiler from rounding the pointer down, thus producing a valid one. “Converted” does not require bit copy. I don’t see how this interpretation is against any section of the spec.

[deleted]

Re: Everything in C is undefined behavior

#100

Earlier quoted context omitted.

The issue is not type punning (itself a very common source of UB), but the fact that the `bytes` pointer might not be int-aligned. The spec is clear that the creation (not just the dereferencing) of an unaligned pointer is UB, see 6.3.2.3 paragraph 7 of the C11 (draft) spec. Of course, this exchange just demonstrates the larger point, that even a world-class expert in low level programming can easily make mistakes in…

> Of course, this exchange just demonstrates the larger point, that even a world-class expert in low level programming can easily make mistakes in spotting potential UB. A "world-class expert in low level programming" knows that unaligned memory accesses are no problem anymore on most modern CPUs, and that this particular UB in the C standard is bogus and needs to fixed ;)

… it’s only UB if the pointer is actually misaligned. It’s not possible to tell from these two lines whether that’s the case.
Post reply on HN