Live data from Hacker News

Everything in C is undefined behavior

blog.habets.se

101–110 of 748 posts

Re: Everything in C is undefined behavior

#101
post #85

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."

> -Acceptance: "Just dont write UB." Just switch to a saner language. And before I get attacked for being a Rust shill, I meant Java :P The bar is so low it's floating near the center of the Earth.

[flagged]

Re: Everything in C is undefined behavior

#102
post #71

Very bad advice. Of course good new LLM's know about UB, but you still need to use ubsan (ie - fsanitize=undefined), and not your LLM.

Coding agents write unsound Rust any day, too. unsafe impl Send … is much easier than fixing a bad design and it might even work momentarily.

Re: Everything in C is undefined behavior

#103
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…

[deleted]

Re: Everything in C is undefined behavior

#104
post #79

The examples aren't really undefined behavior. They are examples that could become UB based on input/circumstances. Which if you are going to be that generous, every function call is UB because it could exceed stack space. Which is basically true in any language (up to the equivalent def of UB in that language). I feel like c has enough actual rough edges that deserve attention that sensationalism like this muddies f…

Ada 83 has no UB on call stack overflow, from the reference manual : http://archive.adaic.com/standards/83lrm/html/lrm-11-01.html "STORAGE_ERROR This exception is raised in any of the following situations: (...) or during the execution of a subprogram call, if storage is not sufficient."

So it's just as useful as when your stack area ends with a page that will segfault on access, or your CPU will raise an interrupt if stack pointer goes beyond a particular address?

It's not safe though because throwing an exception, panicking, etc, is still a denial of service. It's just more deterministic than silently overwriting the heap instead. If the program is critical then you need to be able to statically prove the full size of the stack, which you can do with C and C++ with the right tools and restrictions.

Re: Everything in C is undefined behavior

#105

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.

> Otherwise, when converted back again, the result shall compare equal to the original pointer.

Doesn't this part exclude the possibility of rounding down?

Re: Everything in C is undefined behavior

#106
The UB in unaligned pointers is even worse: an unaligned pointer in itself is UB, not only an access to it. So even implicit casting a void*v to an int*i (like 'i=v' in C or 'f(v)' when f() accepts an int*) is UB if the cast pointer is not aligned to int.

It is important to understand that this is a C level problem: if you have UB in your C program, then your C program is broken, i.e., it is formally invalid and wrong, because it is against the C language spec. UB is not on the HW, it has nothing to do with crashes or faults. That cast from void* to int* most likely corresponds to no code on the HW at all -- types are in C only, not on the HW, so a cast is a reinterpretation at C level -- and no HW will crash on that cast (because there is not even code for it). You may think that an integer value in a register must be fine, right? No, because it's not about pointers actually being integers in registers on your HW, but your C program is broken by definition if the cast pointer is unaligned.

Re: Everything in C is undefined behavior

#107
post #87
post #84

Earlier quoted context omitted.

Unvalidated input can always be an exploit vector.

Except in C, validation of user input can in itself be an exploit vector.

That’s true in other languages as well. Any programmatic task can end up being an exploit vector.

Re: Everything in C is undefined behavior

#108
post #89

Earlier quoted context omitted.

It would already help a lot when the C and C++ standards start to clean up the list of Undefined Behaviour (e.g. there's a lot of nonsense UB currently in the C standard which could easily become Defined Behaviour - like the "file doesn't end in a new-line character" thing): https://gist.github.com/Earnestly/7c903f481ff9d29a3dd1

The easy cases like you cite are also those that don’t cause problems in practice. I’m not sure that would help all that much, other than to slightly reduce internet criticism.

Fixing easy cases makes the list shorter, so enables more focus on harder cases.

And it also signals that you actually do want to improve, just a little bit of boy scout rule goes a long way.

Re: Everything in C is undefined behavior

#109
post #85

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."

> -Acceptance: "Just dont write UB." Just switch to a saner language. And before I get attacked for being a Rust shill, I meant Java :P The bar is so low it's floating near the center of the Earth.

> 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.

Re: Everything in C is undefined behavior

#110
C is still, by far, the simplest language that we have.

Although many newer languages are safer (with the exclusion of Rust, primarily by being slower) the same kinds of issues that are there in C are there in these languages, their effects are just harder to see.

People complain about C as though they know how to fix it.

Post reply on HN