That's exactly the kind of thing that the boosters of all those previous efforts said. But somehow it never quite worked out.
That's exactly the kind of thing that the boosters of all those previous efforts said. But somehow it never quite worked out.
I don't think this is true. - D, Swift, Rust, Zig: different languages, and while they do have FFI, using it means you're only as safe as your C code - CHERI: requires hardware support to be practical - Checked C, CCured, ?SAFECode IIRC?: too expensive - AddrSan@runtime, ARM MTE, SoftBound: mitigations with too many holes
I don't know of many (to be honest, can't think of any) other serious attempts at making a system that tries to cover all three of
A) lets you write normal C
B) covers all the gaps
C) doesn't kill performance
Maybe 3/3 depending on your workload and definition of "killing performance". It's less than 2x slower for some stuff.
The good news is Fil-C is getting faster all the time, and there are still so many obvious optimizations that I haven't gotten around to.
Getting these things to mass deployment, ticking all those little boxes, is a lot of effort. Porting a distribution to a new CPU architecture is likely easier, especially after the early stages (toolchain bringup).
Apart from that, there could be technical issues with the proposed approach. Perhaps the memory overhead? Or it might turn out that the desired performance characteristics basically require a JIT that specializes code so that typed pointers can be used where the types are known to be correct.
> It's not widely known, and it seems to be still in the research stage.
Yes on both counts.
> A lot of things in this area never really get out of that.
I hope that doesn't happen to Fil-C, but it could!
> Getting these things to mass deployment, ticking all those little boxes, is a lot of effort.
100%
I think this is one area where I'm trying to make Fil-C different than what came before it. I'm trying to tick all those little boxes. It's a lot of work!
> Porting a distribution to a new CPU architecture is likely easier, especially after the early stages (toolchain bringup).
Not sure about this. It might be true today because Fil-C hasn't yet ticked all the boxes, but the aim is definitely to be close to the cost of porting to a new CPU. It's already like that for a lot of code.
> Perhaps the memory overhead?
Heh yeah. The invisicaps cost memory. And GC costs memory.
> Or it might turn out that the desired performance characteristics basically require a JIT that specializes code so that typed pointers can be used where the types are known to be correct.
I've thought about how a JIT might help. I don't think it would. (Most of my compiler experience is writing JITs and I wrote JavaScriptCore's JITs, so I'm biased towards seeing JIT opt opportunities - and I don't see any in Fil-C right now.)
I’ll summarize: language implementations get faster over time. Young ones tend to be slow. Fil-C is a young implementation that still has lots of unoptimized things. Also, Fil-C being 2x slower than C means it’s already faster than many safe languages. And, for a lot of C use cases perf doesn’t matter as much as the hype suggests.
The fact that young implementations are slow is something that’s worth understanding even if you don’t care about fil-C. It suggests, for example, that if someone invents a new language and their initial implementation is slow, then you can’t use that fact to assume that it’ll be slow forever. I think that’s generally a useful lesson.
I care about performance a lot and Fil-C has gotten about 100x faster since the first prototype. It’ll keep getting faster.
Here's one: even just switching from gcc or msvc to clang, in projects that really want to, takes years.
Here's another one: the Fil-C compiler is really young, so it almost certainly still has bugs. Those compilers that folks actually use in anger tend to get qualified on ~billions of lines of code before anyone other than the compiler devs touches them. The Fil-C compiler is too young to have that level of qualification.
So "immediately everywhere" isn't going to happen. At best it'll be "over a period of time and incrementally".
https://docs.oracle.com/en/operating-systems/solaris/oracle-...
No, they really didn't. Let's review some of the big cases.
- SafeC: not based on a mainstream C compiler, so can't handle gcc/clang extensions (Fil-C can). Had no story for threads or shared memory (Fil-C does). Hence, not really compatible.
- CCured: incompatible (cannot compile C code with it without making changes, or running their tool that tries to automate the changes - but even then, common C idioms like unions don't quite work). Didn't use a major C compiler,
- SoftBound: not totally memory safe (no attempt to provide safety for linking or function calls). But at least it's highly compatible.
I can list more examples. Fil-C is the first to get both compatibility and safety right.
Has any impartial third party reached that conclusion? Because honestly the way I remember it everyone says this kind of thing when it's their own project, a lot of the people behind these previous efforts were just as confident as you are.
Language implementations get faster over time and young ones tend to be slow. The Fil-C implementation is young. So were all of the previous attempts at memory-safe C - usually an implementation that had years of at most a few person years of investment (because it was done in an academic setting). Young implementations tend to be slow because the optimization investment hasn't happened in anger. So, "past academic attempts were slow" is not a great reason to avoid investigating memory safe C.
Performance focus is not the reason why all of the world's C/C++ code gets written. Maybe that's even a minority reason. Lots of stuff uses C/C++ because of reasons like:
- It started out in C/C++ so it continues to be in C/C++. So many huge projects are in this boat.
- You're critically relying on a library whose only bindings are in C/C++, or the C/C++ bindings are the most mature, or the most easy to use.
- You're doing low-level systems stuff, and having pointers that you can pass to syscalls is a core part of your logic.
- You want to play nice with the dynamic linking situation on the OS you're targeting. (C/C++ get dynamic linking right in a way other languages don't.)
I'd guess less than half of the C/C++ code that's being written today is being written because the programmer was thinking "oh man, this'll be too slow in any other language".
Finally, Fil-C is already faster than a lot of memory safe languages. It's just not as fast as Yolo-C, but I don't think you can safely bet that this will be true forever.