Live data from Hacker News

Undefined Behavior in C and C++ (2024)

russellw.github.io

41–50 of 234 posts

Re: Undefined Behavior in C and C++ (2024)

#41

A couple of solutions in development (but already usable) that more effectively address UB: i) "Fil-C is a fanatically compatible memory-safe implementation of C and C++. Lots of software compiles and runs with Fil-C with zero or minimal changes. All memory safety errors are caught as Fil-C panics." "Fil-C only works on Linux/X86_64." ii) "scpptool is a command line tool to help enforce a memory and data race safe su…

Fil-C is interesting because as you'd expect it takes a significant performance penalty to deliver this property, if it's broadly adopted that would suggest that - at least in this regard - C programmers genuinely do prioritise their simpler language over mundane ideas like platform support or performance.

The resulting language doesn't make sense for commercial purposes but there's no reason it couldn't be popular with hobbyists.

Re: Undefined Behavior in C and C++ (2024)

#42
post #10
post #4

Earlier quoted context omitted.

I find with C/++ I have to compile to find warnings and errors, while with Rust I get more information automatically due to the modern type and linking systems. As a result I compile Rust significantly less times which is a massive speed increase. Rusts tooling is hands down better than C/++ which aids to a more streamlined and efficient development experience

> Rusts tooling is hands down better than C/++ which aids to a more streamlined and efficient development experience Would you expand on this? What was your C tooling/workflow that was inferior to your new Rust experience?

Not the GP, but the biggest one is dependency management. Cargo is just extremely good.

As for the language tooling itself, static and runtime analyzers in C and C++ (and these are table stakes at this point) do not come close to the level of accuracy of the Rust compiler. If you care about writing unsafe code, Miri is orders of magnitude better at detecting UB than any runtime analyzer I've seen for C and C++.

Re: Undefined Behavior in C and C++ (2024)

#43
post #23

>Uninitialized data They at least fixed this in c++26. No longer UB, but "erroneous behavior". Still some random garbage value (so an uninitialized pointer will likely lead to disastrous results still), but the compiler isn't allowed to fuck up your code, it has to generate code as if it had some value.

It won't be a "random garbage value" but is instead a value the compiler chose.

In effect if you don't opt out your value will always be initialized but not to a useful value you chose. You can think of this as similar to the (current, defanged and deprecated as well as unsafe) Rust std::mem::uninitialized()

There were earlier attempts to make this value zero, or rather, as many 0x00 bytes as needed, because on most platforms that's markedly cheaper to do, but unfortunately some C++ would actually have worse bugs if the "forgot to initialize" case was reliably zero instead.

Re: Undefined Behavior in C and C++ (2024)

#44

Earlier quoted context omitted.

Yes, based on a few attempts chronicled in articles from different sources, Rust is a weak choice for game development, because it's too time-consuming to refactor.

We've only had 6-7 years of hame dev in rust. Bevy is coming along nicely and will hopefully remove these pain points

"Mit dem Angriff Steiner's wird das alles in Ordnung kommen" ;)

As shitty as C++ is from today's PoV, the entire gaming industry switched over within around 3 years towards the end of the 90s. 6..7 years is a long time, and a single engine (especially when it's more or less just a runtime without editor and robust asset pipeline) won't change the bigger picture that Rust is a pretty poor choice for gamedev.

Re: Undefined Behavior in C and C++ (2024)

#45
post #7

One has to add that from the 218 UB in the ISO C23, 87 are in the core language. From those we already removed 26 and are in progress of removing many others. You can find my latest update here (since then there was also some progress): https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3529.pdf

A lot of that work is basically fixing documentation bugs, labelled "ghosts" in your text. Places where the ISO document is so bad as a description of C that you would think there's Undefined Behaviour but it's actually just poorly written. Fixing the document is worthwhile, and certainly a reminder that WG21's equivalent effort needs to make the list before it can even begin that process on its even longer document,…

Fixing the actual problems is work-in-progress (as my document also indicates), but naturally it is harder.

But the original article also complains about the number of trivial UB.

Re: Undefined Behavior in C and C++ (2024)

#46

A couple of solutions in development (but already usable) that more effectively address UB: i) "Fil-C is a fanatically compatible memory-safe implementation of C and C++. Lots of software compiles and runs with Fil-C with zero or minimal changes. All memory safety errors are caught as Fil-C panics." "Fil-C only works on Linux/X86_64." ii) "scpptool is a command line tool to help enforce a memory and data race safe su…

Fil-C is interesting because as you'd expect it takes a significant performance penalty to deliver this property, if it's broadly adopted that would suggest that - at least in this regard - C programmers genuinely do prioritise their simpler language over mundane ideas like platform support or performance. The resulting language doesn't make sense for commercial purposes but there's no reason it couldn't be popular w…

Well, you could also treat Fil-C as a sanitiser, like memory-san or ub-san:

Run your test suite and some other workloads under Fil-C for a while, fix any problems report, and if it doesn't report any problems after a while, compile the whole thing with GCC afterwards for your release version.

Re: Undefined Behavior in C and C++ (2024)

#47
post #21

Earlier quoted context omitted.

There's also the fact that a lot of patterns that are commonly used in game development are fundamentally at odds with the borrow checker. Relevant: https://youtu.be/4t1K66dMhWk?si=dZL2DoVD94WMl4fI

Basically all of those problems originate with the tradition of conflating pointers and object identity, which is a problem in Rust as soon as you have ambiguous ownership or incongruent access patterns. It's also very often not the best way to identify objects, for many reasons, including performance (spatial locality is a big deal). These problems go away almost completely by simply using `EntityID` and going throu…

The video I linked to is long but goes through all of this.

Pretty much nobody writing games in C++ uses raw pointers in entities to hold references to other related entities, because entities can be destroyed at any time and there's no simple way for a referring entity to know when a referenced entity is destroyed.

Using some sort of entity ID or entity handle is very common in C++, the problem is that when implementing this sort of system in Rust, developers often end up having to effectively "work around" the borrow checker, and they end up not really gaining anything in terms of correctness over C++, ultimately defeating the purpose of using Rust in the first place, at least for that particular system.

Re: Undefined Behavior in C and C++ (2024)

#48

Undefined behavior only means that ISO C doesn't give requirements, not that nobody gives requirements. Many useful extensions are instances where undefined behavior is documented by an implementation. Including a header that is not in the program, and not in ISO C, is undefined behavior. So is calling a function that is not in ISO C and not in the program. (If the function is not anywhere, the program won't link. Bu…

> Undefined behavior only means that ISO C doesn't give requirements, not that nobody gives requirements. Many useful extensions are instances where undefined behavior is documented by an implementation. True, most compilers have sane defaults in many cases for things that are technically undefined (like take sizeof(void ) or do pointer arithmetic on something other than a char ). But not all of these cases can be sa…

> [...] undefined behavior, executing e.g. both the true and the false branch of an if-statement or none etc.

Or replacing all you mp3s with a Rick Roll. Technically legal.

(Some old version of GHC had a hilarious bug where it would delete any source code with a compiler error in it. Something like this would technically legal for most compiler errors a C compiler could spot.)

Re: Undefined Behavior in C and C++ (2024)

#49

We switched to Rust. Generally, are there specific domains or applications where C/C++ remain preferable? Many exist—but are there tasks Rust fundamentally cannot handle or is a weak choice?

Prototyping in any domain. It's nice to do some quick&dirty way to rapidly evaluate ideas and solutions.

Re: Undefined Behavior in C and C++ (2024)

#50
post #5

Rust here rust there. We are just talking about C not rust. Why we have to using rust. If you talking memory safety why there is no one recommends Ada language instead of rust. We have zig, Hare, Odin, V too.

> Ada language instead of rust Because it never achieved mainstream success? And Zig for example is very much not memory safe. Which a cursory search for ”segfault” in the Bun repo quickly tells you. https://github.com/oven-sh/bun/issues?q=is%3Aissue%20state%3...

> Because it never achieved mainstream success?

And with this attitude it never will. With Rust's hype, it would.

Post reply on HN