Live data from Hacker News

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

hwisnu.bearblog.dev

161–170 of 277 posts

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

#161
post #142

This is a great example of how ADTs can be implemented in C by emulating classes, despite the loss in brevity. For the first item on reference counting, batched memory management is a possible alternative that still fits the C style. The use of something like an arena allocator approximates a memory lifetime, which can be a powerful safety tool. When you free the allocator, all pages are freed at once. Not only is th…

> This is a great example of how ADTs can be implemented in C by emulating classes, despite the loss in brevity.

I don't see it that way, mostly because ADTs don't require automatic destructors or GC, etc, but also because I never considered a unique/shared pointer type to be an abstract data type

> When you free the allocator, all pages are freed at once. Not only is this less error prone, but it can decrease performance.

How does it decrease performance? My experience with arenas is that they increase performance at the cost of a little extra memory usage.

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

#162

Earlier quoted context omitted.

It is surprisingly hard to find information about it, do you have any ? From what I can guess it's a new syntax but it's the feature itself is still an extension ?

[[ ]] attributes were added in C++11 and later C23. There are 7 standard(C32) attributes but GCC has hundreds of them. https://en.cppreference.com/w/c/language/attributes.html https://en.cppreference.com/w/cpp/language/attributes.html https://gcc.gnu.org/onlinedocs/gcc/Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attribute...

Also clang's https://clang.llvm.org/docs/AttributeReference.html

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

#163
post #56

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…

I'd think a POSIX mutex--a standard API that I not only could implement anywhere, but which has already been implemented all over the place--is way more "cross platform" than use of atomics.

If you're targeting a vaguely modern C standard, atomics win by being part of the language. C11 has atomics and it's straightforward to use them to implement thread-safe reference counting.

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

#164

Earlier quoted context omitted.

I think that's an orthogonal issue. It's not that C++'s shared pointer is not a zero cost abstraction (it's as much a zero cost abstraction as in Rust), but that it only provides one type of a shared pointer. But I suppose we're wasting time on useless nitpicking. So, fair enough.

I think they’re one and the same: C++ doesn’t have program-level thread safety by construction, so primitives like shared pointers need to be defensive by default instead of letting the user pick the right properties for their use case. Edit: in other words C++ could provide an equivalent of Rc, but we’d see no end of people complaining when they shoot themselves in the foot with it. (This is what “zero cost abstract…

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

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

#165
post #164

Earlier quoted context omitted.

I think they’re one and the same: C++ doesn’t have program-level thread safety by construction, so primitives like shared pointers need to be defensive by default instead of letting the user pick the right properties for their use case. Edit: in other words C++ could provide an equivalent of Rc, but we’d see no end of people complaining when they shoot themselves in the foot with it. (This is what “zero cost abstract…

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.

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

#166
post #151

Earlier quoted context omitted.

Unfortunately, for C++, thats not true. At least with glibc and libstdc++, if you do not link with pthreads, then shared pointers are not thread-safe. At runtime it will do a symbol lookup for a pthreads symbol, and based off the result, the shared pointer code will either take the atomic or non-atomic path. I'd much rather it didnt try to be zero-cost and it always used atomics...

True, but that's a fault of the implementation, which assumes POSIX is the only thing in town & makes questionable optimization choices, rather that of the language itself (for reference, the person above is referring to what's described here: https://snf.github.io/2019/02/13/shared-ptr-optimization/ )

> the language itself

The "language" is conventionally thought of as the sum of the effects given by the { compiler + runtime libraries }. The "language" often specifies features that are implemented exclusively in target libraries, for example. You're correct to say that they're not "language features" but the two domains share a single label like "C++20" / "C11" - so unless you're designing the toolchain it's not as significant a difference.

We're down to ~three compilers: gcc, clang, MSVC and three corresponding C++ libraries.

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

#167

Earlier quoted context omitted.

Does there exist any platform which has multithreading but not atomics? Such a platform would be quite impractical as you can't really implement locks or any other threading primitive without atomics.

Certainly such systems can pretty readily exist. You merely need atomic reads/writes in order to implement locks. You can't create userspace locks which is a bummer, but the OS has the capability of enforcing locks. That's basically how early locking worked. The main thing needed to make a correct lock is interrupt protection. Something every OS has. To go fast, you need atomic operations. It especially becomes impor…

> You merely need atomic reads/writes in order to implement locks.

Nit: while it's possible to implement one with just atomic reads and writes, it's generally not trivial/efficient/ergonomic to do so without an atomic composite read-write operation, like a compare-and-swap.

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

#168

I feel like there might be some value in this header file for some projects, but this is exactly the wrong use case. > In cgrep, parsing command-line options the old way is a breeding ground for CVEs and its bestiary. You have to remember to free the memory on every single exit path, difficult for the undisciplined. No, no, no. Command line options that will exist the entire lifetime of the program are the quintessen…

There are (older) OSes where this is NOT the case. Leaving things un-freed would leak memory after the application has terminated.

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

#169
post #58

This feels AI-generated.

Guarding builtin_expect with __GNUC__ instead of has_builtin might be what you find in elderly codebases that were fed into an llm

No, that's pretty normal. It's the English writing that feels AI.

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

#170
post #158

Earlier quoted context omitted.

> I think an improved C can be memory safe even without GC That's a very interesting belief. Do you see a way to achieve temporal memory safety without a GC, and I assume also without lifetimes?

A simple pointer ownership model can achieve temporal memory safety, but I think to be convenient to use we may need lifetimes. I see no reason this could not be added to C.

A C with lifetimes would be nice, I agree.

Would be awesome if someone did a study to see if it's actually achievable... Cyclone's approach was certainly not enough, and I think some sort of generics or a Hindley-Milner type system might be required to get it to work, otherwise lifetimes would become completely unusable.

Post reply on HN