frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

Open in hackernews

Undefined Behavior in C and C++

https://russellw.github.io/undefined-behavior
32•imadr•3d ago

Comments

VivaTechnics•3d ago
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?
imadr•3d ago
I haven't used Rust extensively so I can't make any criticism besides that I find compilation times to be slower than C
ost-ing•3h ago
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

bch•2h ago
> 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?

simonask•1h ago
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++.

johnisgood•12m ago
Pacman is extremely good, too, for C. :)
ykonstant•2h ago
I also hear that Async Rust is very bad. I have no idea; if anyone knows, how does async in Rust compare to async in C++?
01HNNWZ0MV43FF•2h ago
I am yet to use async in c++, but I did work on a multi threaded c++ project for a few years

Rust is nicer for async and MT than c++ in every way. I am pretty sure.

But it's still mid. If you use Rust async aggressively you will struggle with the borrow checker and the architecture results of channel hell.

If you follow the "one control thread that does everything and never blocks" you can get far, but the language does not give you much help in doing that style neatly.

I have never used Go. I love a lot of Go projects like Forgejo and SyncThing. Maybe Go solved async. Rust did not. C++ did not even add good tagged unions yet.

ykonstant•2h ago
Thanks for the info!
ViewTrick1002•2h ago
> I also hear that Async Rust is very bad.

Not sure where this is coming from.

Async rust is amazing as long as you only mix in one more hard concept. Be it traits, generics or whatever. You can confidently write and refactor heavily multithreaded code without being deathly afraid of race conditions etc. and it is extremely empowering.

The problem comes when trying to write async generic traits in a multithreaded environment.

Then just throwing stuff at the wall and hoping something sticks will quickly lead you into despair.

kazinator•2h ago
The popular C compilers are seriously slow, too. Orders of magnitude compared to C compilers of yesteryear.
uecker•2h ago
Advantages of C are short compilation time, portability, long-term stability, widely available expertise and training materials, less complexity.

IMHO you can today deal with UB just fine in C if you want to by following best practices, and the reasons given when those are not followed would also rule out use of most other safer languages.

lifthrasiir•2h ago
> short compilation time

> IMHO you can today deal with UB just fine in C if you want to by following best practices

In the other words, short compilation time has been traded off with wetware brainwashing... well, adjustment time, which makes the supposed advantage much less desirable. It is still an advantage, I reckon though.

simonask•1h ago
This is a pet peeve, so forgive me: C is not portable in practice. Almost every C program and library that does anything interesting has to be manually ported to every platform.

C is portable in the least interesting way, namely that compilers exist for all architectures. But that's where it stops.

mrheosuper•2h ago
Rust can do inline ASM, so finding a task Rust "fundamentally cannot handle" is almost impossible.
pizza234•2h ago
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.
Defletter•2h ago
Yup, this one (https://news.ycombinator.com/item?id=43824640) comes to mind. The first comment says "Another failed game project in Rust", hinting that this is very common.
bakugo•2h ago
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

simonask•1h ago
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 through `&mut World` for modifications, rather than passing around `EntityPtr`. This pattern gives you a lot of interesting things for free.

bakugo•18m ago
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.

ramon156•2h ago
We've only had 6-7 years of hame dev in rust. Bevy is coming along nicely and will hopefully remove these pain points
flohofwoe•55m ago
"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.

bluetomcat•2h ago
Rust encourages a rather different "high-level" programming style that doesn't suit the domains where C excels. Pattern matching, traits, annotations, generics and functional idioms make the language verbose and semantically-complex. When you follow their best practices, the code ends up more complex than it really needs to be.

C is a different kind of animal that encourages terseness and economy of expression. When you know what you are doing with C pointers, the compiler just doesn't get in the way.

mgaunard•1h ago
Rust forces you to code in the Rust way, while C or C++ let you do whatever you want.
nicoburns•1h ago
> C or C++ let you do whatever you want.

C and C++ force you to code in the C and C++ ways. It may that that's what you want, but they certainly dont let me code how I want to code!

pjmlp•1h ago
Yes, all the industries where C and C++ are the industry standards like Khronos APIs, POSIX, CUDA, DirectX, Metal, console devkits, LLVM and GCC implementation,....

Not only you are faced with creating your own wrappers, if no one else has done it already.

The tooling, for IDEs and graphical debuggers, assumes either C or C++, so it won't be there for Rust.

Ideally the day will come where those ecosystems might also embrace Rust, but that is still decades away maybe.

m-schuetz•15m ago
Prototyping in any domain. It's nice to do some quick&dirty way to rapidly evaluate ideas and solutions.
fattah25•3h ago
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.

ViewTrick1002•3h ago
> 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...

lifthrasiir•2h ago
More accurately speaking, Zig helps spatial memory safety (e.g. out-of-bound access) but doesn't help temporal memory safety (e.g. use-after-free) which Rust excels at.
ViewTrick1002•2h ago
As long as you are using the "releasesafe" build mode and not "releasefast" or "releasesmall".
pjmlp•1h ago
Which is something that even PL/I predating C already had.
johnisgood•14m ago
> Because it never achieved mainstream success?

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

pjmlp•1h ago
None of them solve use after free, for example.

Ada would rather be a nice choice, but most hackers love their curly brackets.

uecker•3h ago
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
ncruces•1h ago
And yet, I see P1434R0 seemingly trying to introduce new undefined behavior, around integer-to-pointer conversions, where previously you had reasonably sensible implementation defined behavior (the conversions “are intended to be consistent with the addressing structure of the execution environment").

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p14...

tialaramex•1h ago
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, but practical C programmers don't read the document and since this UB was a "ghost" they weren't tripped by it. Removing items from the list this way does not translate to the meaningful safety improvement you might imagine.

There's not a whole lot of movement there towards actually fixing the problem. Maybe it will come later?

uecker•20m ago
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.

kazinator•2h ago
In C, using uninitialized data is undefined behavior only if:

- it is an automatic variable whose address has not been taken; or

- the uninitialized object' bits are such that it takes on a non-value representation.

laauraa•2h ago
>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.

kazinator•2h ago
C also fixed it in its way.

Access to an uninitialized object defined in automatic storage, whose address is not taken, is UB.

Access to any uninitialized object whose bit pattern is a non-value, likewise.

Otherwise, it's good: the value implied by the bit pattern is obtained and computation goes on its merry way.

tialaramex•56m ago
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.

kazinator•2h ago
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. But if it is somewhere, then ISO C has nothing to say about its behavior.)

Correct, portable POSIX C programs have undefined behavior in ISO C; only if we interpret them via IEEE 1003 are they defined by that document.

If you invent a new platform with a C compiler, you can have it such that #include <windows.h> reformats all the attached storage devices. ISO C allows this because it doesn't specify what happens if #include <windows.h> successfully resolves to a file and includes its contents. Those contents could be anything, including some compile-time instruction to do harm.

Even if a compiler's documentationd doesn't grant that a certain instance of undefined behavior is a documented extension, the existence of a de facto extension can be inferred empirically through numerous experiments: compiling test code and reverse engineering the object code.

Moreover, the source code for a compiler may be available; the behavior of something can be inferred from studying the code. The code could change in the next version. But so could the documentation; documentation can take away a documented extension the same way as a compiler code change can take away a de facto extension.

Speaking of object code: if you follow a programming paradigm of verifying the object code, then undefined behavior becomes moot, to an extent. You don't trust the compiler anyway. If the machine code has the behavior which implements the requirements that your project expects of the source code, then the necessary thing has been somehow obtained.

pjmlp•1h ago
Unfortunely it also means that when the programmer fails to understand what undefined behaviour is exposed on their code, the compiler is free to take advantage of that to do the ultimate performance optimizations as means to beat compiler benchmarks.

The code change might come in something as innocent as a bug fix to the compiler.

throw-qqqqq•1h ago
> 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 saved by sane defaults.

Undefined behavior means the compiler can replace the code with whatever. So if you e.g. compile optimizing for size, the compiler will rip out the offending code, as replacing it with nothing yields the greatest size optimization.

See also John Regehr's collection of UB-Canaries: https://github.com/regehr/ub-canaries

Snippets of software exhibiting undefined behavior, executing e.g. both the true and the false branch of an if-statement or none etc. UB should not be taken lightly IMO...

eru•16m ago
> [...] 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.)

pizlonator•1h ago
I don’t buy the “it’s because of optimization argument”.

And I especially don’t buy that UB is there for register allocation.

First of all, that argument only explains UB of OOB memory accesses at best.

Second, you could define the meaning of OOB by just saying “pointers are integers” and then further state that nonescaping locals don’t get addresses. Many ways you could specify that, if you cared badly enough. My favorite way to do it involves saying that pointers to locals are lazy thunks that create addresses on demand.

j16sdiz•12m ago
> First of all, that argument only explains UB of OOB memory accesses at best.

It explains many loop-unroll and integer overflow as well.

safercplusplus•1h ago
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 subset of C++. It's designed to work with the SaferCPlusPlus library. It analyzes the specified C++ file(s) and reports places in the code that it cannot verify to be safe. By design, the tool and the library should be able to fully ensure "lifetime", bounds and data race safety." "This tool also has some ability to convert C source files to the memory safe subset of C++ it enforces"

tialaramex•1h ago
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.

eru•18m ago
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.

roman_soldier•55s ago
Just use Zig, it fixes all this

StarDict sends X11 clipboard to remote servers

https://lwn.net/SubscriberLink/1032732/3334850da49689e1/
207•pabs3•6h ago•136 comments

GLM-4.5: Agentic, Reasoning, and Coding (ARC) Foundation Models [pdf]

https://www.arxiv.org/pdf/2508.06471
277•SerCe•9h ago•41 comments

Wikipedia loses challenge against Online Safety Act

https://www.bbc.com/news/articles/cjr11qqvvwlo
859•phlummox•18h ago•663 comments

A fast, low-latency, open-hardware e-paper monitor and dev kit

https://www.crowdsupply.com/modos-tech/modos-paper-monitor
64•RossBencina•3d ago•13 comments

I tried every todo app and ended up with a .txt file

https://www.al3rez.com/todo-txt-journey
1075•al3rez•20h ago•630 comments

The Article in the Most Languages

https://en.wikipedia.org/wiki/Wikipedia:Wikipedia_Signpost/2025-08-09/Disinformation_report
98•vhcr•3d ago•27 comments

Undefined Behavior in C and C++

https://russellw.github.io/undefined-behavior
32•imadr•3d ago•52 comments

Artificial biosensor can better measure the body's main stress hormone

https://medicalxpress.com/news/2025-07-artificial-biosensor-body-main-stress.html
14•PaulHoule•3d ago•2 comments

Claude Code is all you need

https://dwyer.co.za/static/claude-code-is-all-you-need.html
658•sixhobbits•20h ago•373 comments

GitHub is no longer independent at Microsoft after CEO resignation

https://www.theverge.com/news/757461/microsoft-github-thomas-dohmke-resignation-coreai-team-transition
1212•Handy-Man•18h ago•883 comments

Weathering Software Winter (2022)

https://100r.co/site/weathering_software_winter.html
84•todsacerdoti•7h ago•33 comments

The Best Line Length

https://blog.glyph.im/2025/08/the-best-line-length.html
9•zdw•3d ago•1 comments

Show HN: I built an offline, open‑source desktop Pixel Art Editor in Python

https://github.com/danterolle/tilf
142•danterolle•12h ago•34 comments

CoLoop (YC S21) Is Hiring AI Engineers in London

1•mrlowlevel•3h ago

FreeBSD Scheduling on Hybrid CPUs

https://wiki.freebsd.org/Scheduler/Hybrid
76•fntlnz•4d ago•20 comments

OpenSSH Post-Quantum Cryptography

https://www.openssh.com/pq.html
409•throw0101d•22h ago•108 comments

All known 49-year-old Apple-1 computer

https://www.apple1registry.com/en/list.html
84•elvis70•3d ago•19 comments

The History of Windows XP

https://www.abortretry.fail/p/the-history-of-windows-xp
91•achairapart•2d ago•43 comments

Neki – sharded Postgres by the team behind Vitess

https://planetscale.com/blog/announcing-neki
207•thdxr•16h ago•33 comments

LLMs' "simulated reasoning" abilities are a brittle mirage

https://arstechnica.com/ai/2025/08/researchers-find-llms-are-bad-at-logical-inference-good-at-fluent-nonsense/
74•blueridge•4h ago•50 comments

What does it mean to be thirsty?

https://www.quantamagazine.org/what-does-it-mean-to-be-thirsty-20250811/
63•pseudolus•11h ago•47 comments

Show HN: Play Pokémon to unlock your Wayland session

https://github.com/AdoPi/wlgblock
100•anajimi•1d ago•41 comments

Launch HN: Halluminate (YC S25) – Simulating the internet to train computer use

60•wujerry2000•19h ago•41 comments

How to teach your kids to play poker: Start with one card

https://www.bloomberg.com/news/articles/2025-08-08/how-to-teach-your-kids-poker-with-one-card-at-age-four
92•ioblomov•3d ago•149 comments

Ollama and gguf

https://github.com/ollama/ollama/issues/11714
147•indigodaddy•16h ago•66 comments

Why tail-recursive functions are loops

https://kmicinski.com/functional-programming/2025/08/01/loops/
114•speckx•3d ago•118 comments

The value of institutional memory

https://timharford.com/2025/05/the-value-of-institutional-memory/
152•leoc•17h ago•82 comments

Japan's largest paper, Yomiuri Shimbun, sues Perplexity for copyright violations

https://www.niemanlab.org/2025/08/japans-largest-newspaper-yomiuri-shimbun-sues-perplexity-for-copyright-violations/
146•aspenmayer•10h ago•65 comments

36B solar mass black hole at centre of the Cosmic Horseshoe gravitational lens

https://academic.oup.com/mnras/article/541/4/2853/8213862?login=false
144•bookofjoe•20h ago•103 comments

AOL to discontinue dial-up internet

https://www.nytimes.com/2025/08/11/business/aol-dial-up-internet.html
197•situationista•1d ago•211 comments