Hacker News new | ask | show | jobs
by gwbas1c 485 days ago
There are plenty of attempts at "safe C-like" languages that you can learn from:

C++ has smart pointers. I personally haven't worked with them, but you can probably get very close to "safe C" by mostly working in C++ with smart pointers. Perhaps there is a way to annotate the code (with a .editorconfig) to warn/error when using a straight pointer, except within a #pragma?

> Just talk to the platform, almost all the platforms speak C. Nothing like Rust's PAL (platform-agnostic layer) is needed. 2) Just talk to other languages, C is the lingua franca

C# / .Net tried to do that. Unfortunately, the memory model needed to enable garbage collection makes it far too opinionated to work in cases where straight C shines. (IE, it's not practical to write a kernel in C# / .Net.) The memory model is also so opinionated about how garbage collection should work that C# in WASM can't use the proposed generalized garbage collector for WASM.

Vala is a language that's inspired by C#, but transpiles to C. It uses the gobject system under the hood. (I guess gobjects are used in some linux GUIs, but I have little experience with it.) Gobjects, and thus Vala, are also opinionated about how automatic memory management should work, (In this case, they use reference counting.), but from what I remember it might be easier to drop into C in a Vala project.

Objective C is a decent object-oriented language, and IMO, nicer than C++. It allows you to call C directly without needing to write bindings; and you can even write straight C functions mixed in with Objective C. But, like C# and Vala, Objective C's memory model is also opinionated about how memory management should work. You might even be able to mix Swift and Objective C, and merely use Objective C as a way to turn C code into objects.

---

The thing is, if you were to try to retrofit a "safe C" inside of C, you have to be opinionated about how memory management should work. The value of C is that it has no opinions about how your memory management should work; this allows C to interoperate with other languages that allow access to pointers.

3 comments

> C# / .Net tried to do that. Unfortunately, the memory model needed to enable garbage collection makes it far too opinionated to work in cases where straight C shines. (IE, it's not practical to write a kernel in C# / .Net.

It was pratical enough for Singularity and Midori.

Those projects failed due to lack of leadership support, not technical issues.

Additionally, Android and ChromeOS are what Longhorn userspace could have looked like if leadership support was there, instead of rebooting the whole approach with C++ and COM, that persists to this day in Windows desktop land, with WinRT doubling down on that approach, and failing as well, again due to leadership.

Gobjects are a nightmare. A poor reimplementation of C++ on top of C. You have to know what "unref" function to call and that type to cast. For all the drawbacks of C++, it would have been less bad than Gobject.
It's less so opinionated and more so that WASM GC spec is just bad and too rudimentary to be anywhere near enough for more sophisticated GC implementations found in JVM and .NET.
It's been awhile since I skimmed the proposal. What I remember is that it was "just enough" to be compatible with Javascript; but didn't have the hooks that C# needs. (I don't remember any mentions about the JVM.)

I remember that the C# WASM team wanted callbacks for destructors and type metadata.

Personally, having spent > 20 years working in C#, destructors is a smell of a bigger problem; and really only useful for debugging resource leaks. I'd rather turn them off in the WASM apps that I'm working on.

Type metadata is another thing that I think could be handled within the C# runtime: Much like IntPtr is used to encapsulate native pointers, and it can be encapsulated in a struct for type safety when working with native code, there can be a struct type used for interacting with non-C# WASM managed objects that doesn't contain type metadata.

Here's the issue which gives an overview of the problems: https://github.com/WebAssembly/gc/issues/77

Further discussion can be found here: https://github.com/dotnet/runtime/issues/94420

Turning off destructors will not help even a little because the biggest pain points are support for byref pointers and insufficient degree of control over object memory layout.