Remix.run Logo
EPWN3D 4 hours ago

Author here, I posted this in Show HN but someone clearly beat me to it. So I'll repost my blurb from there.

Various patterns for safer C programming have been cargo-culting around the industry for decades. Because the language evolves intentionally slowly, these patterns rarely get folded into the language as first-class constructs and are passed down through the generations in a sort of oral tradition of programming.

lib0xc leverages GNUC extensions and C11 features to codify safer C practices and patterns into real APIs with real documentation and real testing. Reduce your casts to and from `void *` with the `context_t` tagged pointer type. Enable type-checked, deferred function invocation with `call_t`. Interrogate structure descriptors with `struct_field_t`. Stop ignoring `-Wint-conversion` and praying you won't regret it when you assign a signed integer to an unsigned integer and use `__cast_signed_unsigned`. These are just a few of lib0xc's standard-library-adjacent offerings.

lib0xc also provides a basic systems programming toolkit that includes logging, unit tests, a buffer object designed to deal with types, a unified Mach-O and ELF linker set, and more.

Everything in lib0xc works with clang's bounds-safety extensions if they are enabled. Both gcc and clang are supported. Porting to another environment is a relatively trivial effort.

It's not Rust, and it's not type safety, but it's not supposed to be. It's supposed to help you make your existing C codebase significantly safer than it was yesterday.

My employer holds the copyright and has permitted its release under the MIT license.

valorzard 4 hours ago | parent [-]

This might be a dumb question, but using this + clang bounds-safety, whats the difference between this and something like Zig or Odin.

What do you think C would need in order to reach the user experience of those languages?

EPWN3D 3 hours ago | parent [-]

> This might be a dumb question, but using this + clang bounds-safety, whats the difference between this and something like Zig or Odin.

I really need to learn more about Zig, but from what I know, there are still worlds of possibilities that a modern, well-designed language offers over something like lib0xc. Zig's ability to evaluate any expression at compile-time is one such example.

But generally, lib0xc gives you bounds-safety everywhere it can. Languages like Zig and Rust give you type-safety to their own degrees, which I think is a superset.

> What do you think C would need in order to reach the user experience of those languages?

Not really having direct user experience, it's hard for me to say. But if I what I can give you is a list of features that would make large parts of lib0xc irrelevant:

1. Protocols/traits

2. Allocating from a caller's stack frame (think, returning the result of `alloca` to the caller)

3. printf format specifiers for stdint.h types and for octet strings

4. Ability to express function parameter lists as structures

5. New sprintf family that returns a value which is always less than or equal to the size passed (no negative values)

Basically, I think that the C standard should be working aggressively to cut down on the use cases for heap allocation and `void *`. And I think that the bounds safety annotations should become first-class language features.

onlyrealcuzzo 22 minutes ago | parent | next [-]

> I really need to learn more about Zig, but from what I know, there are still worlds of possibilities that a modern, well-designed language offers over something like lib0xc.

Doesn't Apple have a nice `defer { }` block for cleanup? Did you include that in lib0xc? I didn't see in on your README.

anthk an hour ago | parent | prev [-]

Wouldn't the last case (void *) hurt embedded C development, or retrogaming with direct memory access and pointers?

debo_ 39 minutes ago | parent [-]

They said "cut down", not "eliminate."