Live data from Hacker News

Giving C a superpower: custom header file (safe_c.h)

hwisnu.bearblog.dev

181–190 of 277 posts

Re: Giving C a superpower: custom header file (safe_c.h)

#182

Earlier quoted context omitted.

Outside of hobbyist things, performance-critical code is the only responsible use case for a non-memory safe language like C in 2025, so of course it does. (Even that window is rapidly closing, though; languages like Rust and Swift can be better than C for perf-critical things because of the immutability guarantees.)

Productivity, portability, stability, mind-share, direct access to OS APIs... there's a lot of reasons to still use C.

Only if the OS is written in C, and has its APIs exposed as C APIs to userspace.

Quite a few OSes don't fit that rule.

Re: Giving C a superpower: custom header file (safe_c.h)

#183
post #80
post #2

C++: "look at what others must do to mimic a fraction of my power" This is cute, but also I'm baffled as to why you would want to use macros to emulate c++. Nothing is stopping you from writing c-like c++ if that's what you like style wise.

No name mangling by default, far simpler toolchain, no dependence on libstdc++, compiles faster, usable with TCC/chibicc (i.e. much more amenable to custom tooling, be it at the level of a lexer, parser, or full compiler). C’s simplicity can be frustrating, but it’s an extremely hackable language thanks to that simplicity. Once you opt in to C++, even nominally, you lose that.

I highly doubt (and some quick checks seem to verify that) any of the tiny CC implementations will support the cleanup extension that most of this post's magic hinges upon.

(Agree on your other points for what it's worth.)

Re: Giving C a superpower: custom header file (safe_c.h)

#184

Earlier quoted context omitted.

shouldn't be individually allocated either, arenas for the win

I think that a blanket should/shouldn't recommendation for arenas isn't right. Arenas are a tradeoff: Pros: preallocating one arena is likely faster than many smaller allocations. Cons: preallocation is most effective if you can accurately predict usage for the arena; if you can't, then you either overshoot and allocate more memory than you need, or undershoot and have to reallocate which might be less performant tha…

>If you aren't preallocating and just using arenas for to free in a group, then I'm going to say using an arena for stuff that is going to be freed by the OS at program exit is adding complexity for no benefit

What makes you think that the program is going to exit anytime soon?

Arenas are useful if you want to execute a complex workflow and when it is over just blow away all the memory it accumulated.

An HTTP server is the textbook example; one arena per request, all memory freed when the request is completed, but there's many many more similar workflows in a running program.

Leaving it for program exit is a luxury only available to those writing toy programs.

Re: Giving C a superpower: custom header file (safe_c.h)

#185
post #77
post #35

Earlier quoted context omitted.

Why would I want to run a garbage collector and deal with it's performance penalties?

IDK about Fil-C, but in Java garbage collector actually speeds up memory management compared to C++ if you measure the throughput. The cost of this is increased worst-case latency. A CLI tool (which most POSIX tools are) would pick throughput over latency any time.

Depending on the CLI tool you could even forego memory management completely and just rely on the OS to clean up. If your program completely reads arbitrary files into memory it's probably not the best idea, but otherwise it can be a valid option. This is likely at least partly what happens when you run a benchmark like this - the C++ one cleans everything up nicely if you use smart pointers or manual memory management, while the Java tool doesn't even get to run GC at all, or if it does it only cleans up a percentage of the objects instead of all of them.

Re: Giving C a superpower: custom header file (safe_c.h)

#187
post #164

Earlier quoted context omitted.

Isn't the point of using atomics that there is virtually no performance penalty in single threaded contexts? IMO "zero cost abstraction" just means "I have a slightly less vague idea of what this will compile to."

No, atomics do have a performance penality compared to the equivalent single threaded code due to having to fetch/flush the impacted cache lines in the eventuality that another thread is trying to atomically read/write the same memory location at the same time.

Atomics have almost no impact when reading, which is what would happen in a shared pointer the vast majority of the time.

Re: Giving C a superpower: custom header file (safe_c.h)

#188
Just use C++. Every single one of these is a horror-show worse reinvention of a C++ feature.

Like, if I was stuck in a C codebase today, [[cleanup]] is great -- I've used this in the past in a C-only shop. But vectors, unique_ptrs, and (awful) shared_ptrs? Just use C++.

Re: Giving C a superpower: custom header file (safe_c.h)

#189

Intentionally or not, this post demonstrates one of the things that makes safer abstractions in C less desirable: the shared pointer implementation uses a POSIX mutex, which means it’s (1) not cross platform, and (2) pays the mutex overhead even in provably single-threaded contexts. In other words, it’s not a zero-cost abstraction. C++’s shared pointer has the same problem; Rust avoids it by having two types (Rc and…

> the shared pointer implementation uses a POSIX mutex Do you have a source for this? I couldn't find the implementation in TFA nor a link to safe_c.h

[deleted]

Re: Giving C a superpower: custom header file (safe_c.h)

#190

Earlier quoted context omitted.

No, atomics do have a performance penality compared to the equivalent single threaded code due to having to fetch/flush the impacted cache lines in the eventuality that another thread is trying to atomically read/write the same memory location at the same time.

Atomics have almost no impact when reading, which is what would happen in a shared pointer the vast majority of the time.

> which is what would happen in a shared pointer the vast majority of the time.

This seems workload dependent; I would expect a lot of workloads to be write-heavy or at least mixed, since copies imply writes to the shared_ptr's control block.

Post reply on HN