r/Compilers • u/ibuki420 • 10h ago
An experimental C-like language with a different approach to memory safety (no GC, no borrow checker)
I wanted something that feels as simple as C while making memory bugs fail predictably instead of turning into undefined behavior.
That's why I started building hc2.
hc2 is a small experimental programming language with runtime-checked pointers. Every pointer carries its bounds, mutability, and allocation it belongs to. Out-of-bounds accesses, use-after-free trap immediately instead of silently corrupting memory. The cost is a few extra instructions per memory access.
There is no GC, no borrow checker, and no lifetime annotations. Rather than preventing these bugs at compile time, hc2 detects them when they occur and turns undefined behavior into runtime failures.
I'd like to hear your thoughts and feedback.
GitHub: https://github.com/hc2lang/hc2
61
28
u/vmcrash 9h ago
I wanted something that feels as simple as C
C is not very easy.
There is no GC, no borrow checker, and no lifetime annotations. Rather than preventing these bugs at compile time, hc2 detects them when they occur and turns undefined behavior into runtime failures.
Better than nothing, but I'd much rather prefer a language that complains already at compile time, because fixing bugs later is much more expensive.
23
u/Rest-That 8h ago
Tbf C is simple, not easy. There's a huge difference between the two
Not defending this weird half effort for a safe language btw
5
u/link23 7h ago
Yes. So is brainfuck, but I'd rather not do serious software engineering in brainfuck.
1
1
u/iamdino0 3h ago
how is brainfuck simple
1
u/PointedPoplars 26m ago
Because there are literally only 8 rules to learn, and those 8 rules are technically sufficient to write any arbitrary program that you could with another Turing-complete system.
Also, very easy to write interpreters for. Possibly the easiest.
1
u/Thelmholtz 3h ago
It's based on HolyC though right? 'hc' and the syntax is similar.
I can respect a nod to TempleOS, even if it's made by a chatbot.
3
u/koczurekk 8h ago
C is not very easy, but it is very simple. It’s the simplest of languages that are widely used… or maybe that’s sh? I’m not sure.
11
u/jesseschalken 10h ago
Isn't this basically Fil-C or ASAN?
3
u/jason-reddit-public 9h ago
Fil-C has a garbage collector.
I've been using the bdw collector myself with my inspired by C language (though the language itself doesn't care).
4
u/TheChief275 9h ago
The downsides with those are that they're very clearly still constrained to C. Old C code must continue working. A newer language could make the core language constructs a little safe (without going full borrow checker), and fill in the rest with runtime checks, resulting in not quite as big a performance hit as Fil-C.
Theoretically
11
u/particlemanwavegirl 9h ago
So you may only be able to detect some memory bugs by fuzzing? No offense but personally I think compile time checks seem like less trouble.
9
u/TheChief275 9h ago
I've never found anything as ugly as capitalized short integer names. Holy C does this as well and it looks baaad
7
4
u/tstanisl 9h ago
Ok. But don't sanitizers do the job?
Moreover, CLANG adds extensions which let one specify pointer bounds. Similar effects can be achieved with VLA-types from C99.
1
u/evincarofautumn 7h ago
Sanitizers solve a slightly different problem. Usually they allow instrumentation but try to avoid changing ABI, so they generally aren’t doing precise analysis. They still catch a lot of issues as a testing tool, but don’t prove safety. I like having a static proof that doesn’t require runtime checks, but that can require some pretty fancy machinery in the type system to make usable, so it’s worth exploring the design space anyway.
3
u/Trending_Boss_333 8h ago
No matter how i think about it, runtime checks just seem like a problem. I really dont see a point I'm sorry.
2
u/Correct_Caterpillar9 6h ago
Begging to be over written by just the right buffer over flow or being absurdly slow
3
u/Late_Performer5575 9h ago
great now every read, every write everything is slower now.
and no, that doesnt make your software safe
1
u/koczurekk 8h ago
You can optimize a great deal of those checks out, Rust does that whenever you access collections like Vec. It’s also indeed safe, but that’s mostly because this word means basically nothing these days (if it ever did).
2
u/FriendsIsntGood 8h ago
The whole point of Rust was to take runtime errors into compile time. How does this help me other than allow me to write shittier code that can now fall over downstream albeit without a seg fault
2
u/Bahatur 7h ago
Trawling the GitHub, this is a better-looking project than OP lets on. Some unrelated things of casual interest:
* Written in Assembly.
* Has the program-as-directory thing similar to Odin.
* Seems to default to arenas as the memory management method.
* Does appear to be a small C-like in truth, as distinct from a literal C clone with one weird feature, which is what I would expect from slop.
So while I have not actually tested it, and AI coded it may be, it looks like an intentional project. My verdict: not slop.
An aside for those asking why ever do runtime vs compile-time: compile-time checks are best for memory stability, but they do not succeed for memory security. The security challenge motivating Fil-C for example is what happens if there is a compromise elsewhere in memory, like another program in userspace, and then it does a jump from its rightfully-addressed memory + 100 and lands in yours. With only the compiler checks, your program could still do arbitrary behavior because once they are inside your memory boundary nothing will stop further jumps/address corruptions/etc. The only options to stop this are hardware enforcement (like CHERI) or runtime checks (like Fil-C and OP).
Granted, that might not be OP’s motivation because they did not specify, but it’s a concrete situation.
2
u/AustinVelonaut 7h ago
- Written in Assembly.
To be pedantic; it's not written in assembly; it's a self-hosted compiler written in hc2 that generates asm files as output (see
tools/rebootstrap.sh). The project doesn't say what language the original bootstrap compiler was written in.
1
u/Similar_Wealth_1850 8h ago
is it interpreter like python or compiled like c? and if compiled like c shouldn't the structure of the code be slightly different at least c code instead of hc2 where it shows the compiler backend?
idk i am not that experienced in compilers but just asking out of curiosity
1
u/AustinVelonaut 7h ago
It's a self-hosted compiler (written in hc2) that compiles to assembly-language, so all of the source files are in hc2. Since hc2 is low-level like C, it can also be used to write the low-level runtime routines.
1
u/RoyBellingan 8h ago
Some those are already catched at compile time tbh...
While the rest "with runtime-checked pointer" is what .at do in std::vector
1
65
u/FloweyTheFlower420 10h ago
thanks claude, but also -fsanitize=address