Live data from Hacker News

Everything in C is undefined behavior

blog.habets.se

671–680 of 748 posts

Re: Everything in C is undefined behavior

#671
post #601

Earlier quoted context omitted.

Author here. > It barely scratches the surface. I agree. The point of the post is not to enumerate and explain the implications of all 283 uses of the word "undefined" in the standard. Nor enumerate all the things that are undefined by omission. The point of the post is to say it's not possible to avoid them. Or at least, no human since the invention of C in 1972 has. And if it's not succeeded for 54 years, "try hard…

> if nobody can do it right, how is it even fair to blame the programmer? My point is that ALL It's fair to blame the programmer for the choice of programming in a language like this, if it was in fact their choice. As you've so eloquently put, choosing those languages is essentially equivalent to choosing UB, so starting a new project with one of them is 100% blameworthy when the UB is inevitably found.

Not all projects are green field. But sure, new modules can be written in other languages. And C is, as cross-language barriers go, fairly easy to interface with.

Re: Everything in C is undefined behavior

#672

Earlier quoted context omitted.

> I've got 40 years of programming in C so far, and the nightmare stories ran out after the first few years. You need to find something more interesting to do ;)

Oh, I do. I'm building a two-story 1000 sq.ft garage right now - more workshop than garage tbh [1], I've just built a roll-off-roof observatory [2], the currently empty pad behind it is for a radio-telescope, last set up in London [3], still needs to be assembled in the new house. Right now I'm into the fun stuff of automating everything in the observatory. I've also recently taken up archery, and I'm enjoying that.…

Ooh, fun! Good luck!

Re: Everything in C is undefined behavior

#673

Earlier quoted context omitted.

Yes, it simplifies a lot of code that would otherwise be littered with casts.

Could be fixed by having a nicer casting syntax (like Rust) or by not having so damn many scalar types that are used in practice. "Explicit casts only" worked fine in Modula-2, which doesn't have as many scalar types.

Yeah most modern languages settle on having fewer types that are used most of the time and don't require as many casts.

Re: Everything in C is undefined behavior

#674

Earlier quoted context omitted.

I think parent commenter made a joke. UB can be seen as "implementation defines this to reformat your hard drive. No we don't document it". That is, the compiler de facto defines what happens when you compile UB code. So you're not wrong, but I think you missed the sarcastic spin of parent.

>That is, the compiler de facto defines what happens when you compile UB code. That is not what undefined behavior is though, that is unspecified behavior. The entire point of undefined behavior is to cover the cases where the compiler can't define the semantics of your program either because doing so is genuinely not possible, or is incredibly onerous to deduce, or would require introducing runtime checks whose perf…

Sorry, by "de facto defines" I meant that it factually does something, even if that "something" is "segfault the compiler at build time".

That "de facto" did some heavy lifting.

Re: Everything in C is undefined behavior

#675

Earlier quoted context omitted.

Is that really a meaningful distinction? Once you are addressing arbitrary values you are firmly in the realm of "anything happening" in practice, but you've now given up optimization opportunities. As has been repeatedly demonstrated over the years, once memory safety breaks it is practically impossible to make any guarantees about program behavior.

Yes, it's a meaningful distinction. No you are not into "anything happening" in practice. Your compiler emitting a load operation and it failing isn't "anything". The failure being handled by code that the compiler authors can't predict doesn't make it "anything". And if you lose optimization opportunities because of this it's because your optimization is broken. By the way, if you lose optimization opportunities bec…

Compilers elide loads all the time this is one of the more basic optimizations a compiler can do. We just mostly think those are "good" optimizations.

Re: Everything in C is undefined behavior

#676

Earlier quoted context omitted.

I think it’s a really easy sell, actually: if you go past the end of the array far enough you end up accessing the stack which includes parts of the program like “where does this function return to” or “what is the index used to perform this access” or “there is no page mapped there”. None of these are arbitrary values.

The "anything can happen" means that the compiler can simply silently refuse to emit the code does the access. Documenting that the instructions to access will always be eliminated makes it easier to predict what will happen.

Yes, but usually you don't want this. You think you do, but you don't: you can't always eliminate these, and often eliminating the extra accesses is not the most efficient thing to do either. Sometimes it's faster to have the loads and not check, sometimes you can check and skip that path, etc.

Re: Everything in C is undefined behavior

#677
post #622

Earlier quoted context omitted.

In practice, GCC -O2 will happily erase entire swathes of code and turn perfectly logical source into nonsense assembly whenever it gets as much as a sniff of UB anywhere in the code path. Nobody would be talking about UB if GCC wasn't so aggressive in abusing the freedom UB gives. To paraphrase your earlier comment - you lose low-friction polymorphism (unpredictable compiler output causes a lot of friction). You los…

Then I'm almost ashamed to admit that I'm not sure I've ever witnessed any surprising form of UB in the wild. For example, I will reliably get segfaults on NULL dereference in practice. Typical manifestations of UB are entirely predictable and obvious. Of course I'm also running most code without most optimizations, most of the time, while developing. On the other hand, what I've observed with my own eyes is interest…

Compilers do not surprise all that often which is why it is extra surprising when it does happen

Re: Everything in C is undefined behavior

#678

Earlier quoted context omitted.

> The reason for the hack is that very early C compilers just always spill, so you can write MMIO driver code by setting a pointer to point at the MMIO hardware and it actually works because every time you change x the CPU instruction performs a memory write. Source?

Source for what? The volatile keyword is explicitly telling the compiler "don't optimize read/write to this memory location". That's the whole point. Its use for manipulating hardware registers is covered in any intro embedded systems course. I don't know the history of C compilers but it would seem reasonable to assume that compilers started out plainly translating the C to machine code. Optimization would have happ…

Source for "compilers basically always did volatile since everything was always spilled".

Re: Everything in C is undefined behavior

#679
post #30

Debugging in C is soooo hard. When I was writing Malloc Lab in system course, there were uncountable undefined and out of range :(

I think vice versa - C is so simply, that debugging it is just a pleasant walk.

Especially compared with modern languages with lambdas/exceptions/virtual functions and so on.

The one thing I see can make it harder is function pointers.

Re: Everything in C is undefined behavior

#680

Earlier quoted context omitted.

Wouldn't that make a compiler that emitted bounds checks violate the standard, since it would not be emitting the actual memory operations if you deref out of bounds?

No, because it's UB so there is no standard.

Isn't the proposal from the parent comment to define the behavior?
Post reply on HN