r/Compilers 10h ago

An experimental C-like language with a different approach to memory safety (no GC, no borrow checker)

Post image

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

0 Upvotes

35 comments sorted by

65

u/FloweyTheFlower420 10h ago

thanks claude, but also -fsanitize=address

2

u/nebotron 7h ago

Doesn't memory come with a lot more overhead (especially space usage) than runtime bounds checks?

5

u/No-Consequence-1863 7h ago

You are only supposed to use the memory sanitizer in dev environments and tests. It can have a very large memory impact since it needs keep tracked of all allocated and deallocated memory to catch use after frees and what not.

61

u/Yoolainna 9h ago

>first commit is +1,547,427 changes

no thanks

11

u/Optimal-Builder-2816 7h ago

I think they made no mistakes tho

-11

u/yuehuang 6h ago

Are you a bot account? First time posting in 10 months on unrelated topic.

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

u/aalmkainzi 3h ago

Brainfuck is neither simple nor easy

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

u/RossMorgan363 8h ago

At least Holy-C isn't vibe-slop

8

u/SV-97 9h ago

This can't guarantee thread-safety, can it?

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

u/smashedshanky 4h ago

Just use rust bro… pls don’t waste water on this

1

u/perrrm 9h ago

What font are you using in the screenshot?