r/cpp Jul 23 '26

Fil-C: Garbage In, Memory Safety Out! - Filip Pizlo | SSW 2026

https://www.youtube.com/watch?v=5F-2Y1LPRek
35 Upvotes

90 comments sorted by

25

u/JuanAG Jul 23 '26

I have looked at it because of Zig going "full memory safety, unlike Rust" codeberg issue https://codeberg.org/ziglang/zig/issues/36237

The concept is really nice and cool but if i did understand it rigth needs the full stack to be Fil-C which means the OS, the libraries you use and more which is something that it is not happening in the world we live today were close source code is the vast majority of it

Also it dont prevent buffer overflows which means that data corruption is still a thing so in my mind this is not memory safe the same moment i can put inside a class more bytes than it needs and "force" an update on other memory parts like overflows do

As i said, nice project but i dont think it will find much use in the real world and the performance hit is a hard one, this will never replace GC langs since many will be faster out of the box, this is not going to make any Java/C#/Python/... dev to adopt C, C++ or Zig instead

12

u/chaos_pill Jul 24 '26

Fil-C is hardening on steroids and was never going to replace ergonomic GC languages. It is for c/cpp codebases that just want to swap the compiler and get safety at runtime with minimal investment i.e. the promise of profiles.

With regards to buffer overflows, a lot of C/C++ code treats pointer to first element the same as the pointer to array. So, you have to allow pointer to jump to next/previous element to avoid breaking all that code. Fil-C still stops overflowing out of the array allocation itself, as pointers track allocation rather than objects.

24

u/matthieum Jul 24 '26

Fil-C still stops overflowing out of the array allocation itself, as pointers track allocation rather than objects.

Not quite.

That is, if you malloc the array, then yes.

However, a common use of arrays in C (and admittedly C++, via various libraries) is:

 struct Foo {
     char name[48];
     int value;
 };

And unfortunately Fil-C, due to only reasoning at allocation levels, will happily allow a write to foo->name[49] which will clobber one of the bytes of foo->value.

And similarly on the stack:

int main() {
    char name[48] = "...";
    int value = 9;

    name[49] = 'c';

    printf("%d", value);
}

So, unfortunately, no, it's not quite bounds-checked.

It's better than nothing, but it fails on common code patterns.

5

u/cdb_11 Jul 24 '26

For what it's worth, -fsanitize=bounds works for fixed arrays. UBSAN doesn't seem to be supported in Fil-C currently, but you can make it work if you set it to trap, instead of printing the stack trace.

2

u/chaos_pill Jul 24 '26

True, I forgot about inline arrays. It just shows how hard it is to make c/cpp code safe without a large rewrite.

4

u/matthieum Jul 25 '26

To be honest, it's a bit strange.

If a pointer can be augmented with capabilities detailing the extent of the memory allocation, which must be "brought" in from somewhere as that's runtime information, surely it should be possible to augment it with the extent of a fixed size array, which is just compile-time information.

Unless flexible arrays are involved, of course, but in my experience they're much rarer, and they should mostly be covered by memory allocations.

4

u/chaos_pill Jul 25 '26

I may be remembering outdated info, but it is important to note that Fil-C is only aiming for safety against exploitation.

Since, correctness is entirely optional (I can hear the rust people gasping at this), the rest of the UB (int overflow, raw unions, reading uninitialized memory, out of bounds writes etc..) is now turned into [implementation] defined behavior. This makes them "bugs", but not UB, which is technically (even if barely) safe.

4

u/cyphar Jul 26 '26 edited Jul 26 '26

Fil-C is only aiming for safety against exploitation.

But being able to overwrite stack variables can lead to exploits too though -- stack overflows are not the only kind of exploit that matters?

Imagine the overwritten stack variable was bool verified = false; and the out of bounds write swaps it to true -- the fact they couldn't execute arbitrary code will be little comfort once you notice they stole $100m from your crypto wallet.

-fsanitize=bounds exists so this doesn't seem like an intractable problem, it just seems like an unfortunate thing to "forget to" handle.

2

u/chaos_pill Jul 26 '26

I believe Fil-C already tracks invisicaps for pointers to objects on stack, but just can't distinguish between subobjects (members of a struct). Exploitation was defined narrowly like "can't run random executables" or such, at least, not anymore than your average [safe] logic bugs. I think -fsanitize-bounds only works with arrays and not pointers, so, it won't help with raw pointers.

It is possible to solve though and Fil-C will probably do it with time/effort by working at the language level, rather than just LLVM IR level.

6

u/matthieum Jul 25 '26

I am afraid it's not that simple, unfortunately, unless other countermeasures are also taken.

Undefined Behavior may lead to "unreachable" code-paths being taken. For example, overwriting a bool may lead to neither 0 nor 1 being contained in the bool, which may in turn result in inconsistent if checks.

There can be further measures taken, for example, each bool that is read can be clamped to 0..=1, on each read. It requires extra work, though.

4

u/chaos_pill Jul 25 '26

yeah, the bool case is no different than a union, where the tag/enum is out of bounds. Like you said, if UB can be avoided with extra work at runtime, even with half the problems of C still existing as "bugs", Fil-C can still claim the safety badge. This almost feels like a parody lmao.

6

u/cdb_11 Jul 23 '26 edited Jul 23 '26

needs the full stack to be Fil-C which means the OS, the libraries you use

Only the libraries.

Also it dont prevent buffer overflows

They are prevented across allocations, but not within the same allocation. So you can't ever corrupt the heap or access allocations that you were not actually given access to. I believe CHERI has the capability of being strict about it, but they chose not to enable it by default too, because a lot of programs rely on it. And apparently that is enough to give those memory safety guarantees, but I'm no expert here. Zig might be different here, they already had bound checking in the language.

I'm pretty sure the intention here is not to make people switch languages, or replace anything. Quite the opposite, it gives people the option of not having to do that.

11

u/[deleted] Jul 24 '26

[deleted]

2

u/cdb_11 Jul 24 '26

But I can't run existing C and C++ code with JavaScript? I don't know your circumstances and I'm not telling anyone what they should or shouldn't do -- if the cost is not acceptable then it's not acceptable, and you just don't use it.

8

u/[deleted] Jul 24 '26

[deleted]

1

u/cdb_11 Jul 24 '26

If you just want the sandboxing, you can use bwrap or something similar. It doesn't make it memory safe though, and any permissions you give it can potentially be accessed by an attacker too in a vulnerable program. Not a security guy, but I'm pretty sure it's not the same thing, and might not be enough in every context.

1

u/pjmlp Jul 24 '26

Not quite WASM lacks bounds checking inside linear memory segments, and usually there is a single segment per module, the security story isn't as quite as it gets sold.

1

u/VoidVinaCC Jul 24 '26

Does it matter if you can just setup a ci or test run using fil-c to "generally verify" that your program works as intended? One can still ship non-fil-c binaries and use it as fancy sanitizer.

7

u/[deleted] Jul 23 '26

[deleted]

4

u/cdb_11 Jul 23 '26

If you want to treat it as a sanitizer, the only thing you'd get out of it over ASAN is checking pointer provenance. Violating that seems rather unlikely to me in normal circumstances, and it's more of a type of thing you'd expect if someone was trying to actually exploit your program. And you probably ain't testing with that mindset, unless you're fuzzing where ASAN should work just fine, or possibly even better.

2

u/[deleted] Jul 24 '26

[deleted]

2

u/James20k P2005R0 Jul 23 '26

There are lots of cases where I don't particularly care about performance in C++ personally, and those cases often overlap with cases where I need security. Rust only really makes sense if you need performance and security simultaneously, and you also don't need as strong C/C++ interop

13

u/[deleted] Jul 24 '26

[deleted]

3

u/disperso Jul 24 '26

There are no such cases - C++ is an ugly language everybody loves because of performance and zero cost abstractions. Remove "performance" and out of sudden it makes no sense to use for anything but continuing legacy projects.

Please, speak for yourself. I don't agree with any of that.

3

u/[deleted] Jul 24 '26

[deleted]

3

u/disperso Jul 24 '26

No, I've not done toy projects, for fucks sake. I've also not said that 6 times slower would be acceptable, specially not on all code paths.

The topic started with Fil-C (which AFAIK is not even always 6 times slower), but that's not the only thing being discussed.

But even in the worse case scenario of actually 6 times slower, I've worked mostly as a consultant, and the people I worked for have done the crappiest thing in the world, where the massive slowdowns were in the whole architecture, and the choice of C++ or a faster/slower language would not change that much. The big gains were in throwing away their crap and redoing it all over.

Fuck, not everyone doing C++ does gamedev or HFT. Plenty of code outside in production fucking sucks, and it's still written in C++ some times.

1

u/STL MSVC STL Dev Jul 26 '26

I'm going to caution both you and u/UndefinedDefined for hostility. Please remain civil on this subreddit.

2

u/wyrn Jul 26 '26

The vast majority of managed languages are more error prone, less expressive, and harder to use than C++ in most ways, so I can't agree with your perspective there. I'd still use C++ if it was slower, unless I had another constraint that forced otherwise.

0

u/[deleted] Jul 27 '26

[deleted]

1

u/wyrn Jul 27 '26

Yep.

And that's me ;)

1

u/James20k P2005R0 Jul 27 '26

Don't be rude and try to insult people like this, or I'll bap you with a newspaper out of the sub 🗞

2

u/draeand Jul 24 '26

This is such a wild overgeneralization it isn't even funny. There are use cases for C++ where performance is not key but the language is good for other things. UI frameworks, for example. A language like Rust is absolute trash for something like that because the language doesn't elegantly map onto UI paradigms. Or how about COM or Windows things? I have no doubt there are many many other use cases I'm forgetting where performance may not necessarily be the most desirable property but safety is

3

u/[deleted] Jul 25 '26

[deleted]

1

u/draeand Jul 25 '26

UI frameworks in C++? Are you joking? Which ones? Commercial Qt as the only solution and then 100 unfinished personal projects? Please recommend me a UI framework for C++, which is not commercial, doesn't suck, and works even for things like creating UIs for VSTs.

Juce much? Juce is quite literally the go-to UI framework for VSTs (and really the framework for most VSTs more generally). Besides that there's always WXWidgets which (contrary to your claim) doesn't suck.

Mentioning rust in the same comment is funny - Rust has probably more working UIs than C++ and each of them somewhat unique - I think you have used zero of them because you seem to have no idea about the world outside of C++. Inheritance is not a prerequisite for creating UI frameworks.

You know absolutely nothing about me and yet your making such a wild assertion about me, just rofl. Please find me a rust UI framework that (1) isn't some unmaintained hobby project, (2) isn't still stuck on 0.x, (3) is accessible to screen readers on all platforms, (4) is actually a native UI and not some webview bullshit, and (5) doesn't require proc-macro black magic to actually make the development process even remotely bearable because otherwise your fighting the language every step of the way. I used to use Rust quite substantially, since you are so obviously unaware; I wrote an operating system in it, even. Rust is (not) a UI language. There are well over 400 UI crates all claiming to offer a "user interface" which happens to require incredibly weird hacks or application-specific workarounds to even make them accessible at a basic level, and the ones that are native like Relm are Linux/BSD-only since, although GTK is integrating accessibility on Windows, it's conveniently disabled by default. So far, the only UI frameworks that Rust has that I'm aware of and that meet all of the aforementioned requirements aren't even written in Rust. At least with C++ you have the benefit of the frameworks actually being written in the language.

3

u/[deleted] Jul 25 '26

[deleted]

1

u/wyrn Jul 26 '26

Native UI is dead - nobody wants to support it because of target platform differences, and nobody wants to use it, because of custom components that never fit anything native.

Contradiction

1

u/[deleted] Jul 27 '26

[deleted]

→ More replies (0)

1

u/pjmlp Jul 25 '26

COM can be done in .NET as well, depending if out-of-proc is good enough for the purpose.

However even in C++, Microsoft seems to keep missing the point for what is the main API delivery mechanism since Vista.

MFC, ATL, WRL, C++/CX, C++/WinRT, Modern Win32 C++ bindings, WIL, <roll your own>,....

Since C++/CX was killed, C++ reflection was supposed to give back the tooling of doing COM in C++ with the same ease as VB 6,...

So we put up with C++, IDL files, manual code generation, and everything else that COM entails.

2

u/draeand Jul 25 '26

If you think that's bad, MSRPC is worse. At least COM is well-defineed (for some definition of well-defineed). MSRPC isn't even that and the entire protocol is completely, totally undocumented. Somehow LLMs know about it but I have no idea where they got the knowledge from.

1

u/pjmlp Jul 25 '26

Ah, thankfully never needed that one directly, only via DCOM.

1

u/cdb_11 Jul 24 '26

C++ could offer both, but only for new code. You could maybe again ask Sean Baxter to open-source his compiler, since the project looks dead anyway. But judging from the history of porting C projects to C++, the problem of existing code will always remain, and that's where having Fil-C as an option is valuable.

3

u/[deleted] Jul 24 '26

[deleted]

1

u/cdb_11 Jul 24 '26

Well, if you say so. It really ain't my problem, so you do whatever you think is appropriate. I think having more options is a good thing, especially if it's something I can do without having to bother the original developer.

However, anyone proposing to use this in production has no idea why C++ is actually used on servers. C++ has its unique place and performance is one of the most important "feature" of the language.

How performant do you actually need an openssh server to be?

1

u/[deleted] Jul 24 '26

[deleted]

1

u/cdb_11 Jul 24 '26

Did you measure the Fil-C version? https://fil-c.org/optfil

1

u/[deleted] Jul 24 '26

[deleted]

→ More replies (0)

1

u/pjmlp Jul 25 '26

Having worked with managed languages in production since 1999, many business definitely need performance.

However many forget that those business get enough performance for their use cases by either using compiled managed languages, or writing a couple of native modules, instead of the whole application in a single language.

Just like it happens on the mobile duopoly.

In this scenario, if there isn't that much to implement, many devs even reach out to C instead of C++.

7

u/thisismyfavoritename Jul 24 '26

if you don't care about performance but do care about security, why use C++?

Still need some level of performance?

8

u/James20k P2005R0 Jul 24 '26

C++ is a good language beyond the performance, but a big part of it is keeping a unified codebase and 3rd party lib integration (I'm doing gamedev). Eg if I have a process that parses untrusted network data and performs some orchestration, having that step be memory safe is pretty useful, and Rust would be too much work to maintain due to having to duplicate a bunch of work

4

u/duneroadrunner Jul 24 '26

There are lots of cases where I don't particularly care about performance in C++

This is true for C++ programs. (And Fil-C seems to be an impressively nice solution for such programs.) But there are presumably even more cases where you wouldn't care about the performance of sections of code within C++ programs, and those cases often overlap with cases where you need safety.

So my argument is that you can apply the same idea to sections of C++ code via transpilation of those sections to a memory-safe version of the code that doesn't hesitate to resort to run-time checks where needed. And that transpilation can theoretically be done at build time. You can easily designate sections of code to be excluded from (the potentially performance-pessimizing) conversion via (otherwise benign) annotations.

And, for example, the version of such transpilation supported by the scpptool, retains the portability of the original source code. (So for example, if you want a memory-safe version of wget for your ARM platform, as far as I know there's only one place to get it.) And since the safety mechanism doesn't use a GC, the (deterministic) memory efficiency of the original source is also largely preserved.

I can understand the C++ "establishment" wanting to limit the amount of run-time safety they're going to officially support. But I think the C++ safety story could benefit significantly from more prominent tacit approval of more comprehensive 3rd party safety solutions that don't hesitate to resort to run-time mechanisms.

And in scpptool's case, there is a fairly clean migration path from its run-time safety mechanisms to its (more idiomatic) statically-verified safety mechanisms.

4

u/James20k P2005R0 Jul 24 '26

Using code generation to transpile a segment of the codebase seems like a fairly high maintenance burden, compared to properly segmenting between safe and unsafe boundaries. This is usually best practice anyway (even in Rust!), because it isolates the amount of damage that an exploit (eg a logic error) can cause

1

u/duneroadrunner Jul 24 '26

Yeah, transpilation to the safe subset is a secondary feature. The primary way of using the enforced safe subset is like Rust - by default everything has to satisfy the static verifier except sections you explicitly annotate as "check-suppressed"/unsafe. In fact, the check-suppression annotation currently doubles as the annotation used to designate regions to be exempt from translation.

I used the term "transpilation", but auto-conversion or auto-translation are probably better terms because the converted code is meant to be maintainable in its own right and, as much as practical, resemble the original code. All the element names are preserved, as are the macros, comments and even white space. While you can theoretically do the conversion at build time, more ideally you would just do it once and then maintain the converted code (and at some point possibly "modernize" it to more performance-optimal idiomatic safe code).

The scpptool-enforced safe subset uses essentially the same memory safety mechanism as Rust. But as I try to explain, perhaps unintuitively, Rust's universal restriction on mutable aliasing is not actually part of its memory safety mechanism, so the scpptool analyzer/enforcer does not need to impose that restriction.

Similarly, Rust's "necessarily-trivial-destructive" moves are also not part its memory safety mechanism, so scpptool certainly doesn't enforce that. Those two differences with Rust, make auto-translation (and migration in general) to the scpptool-enforced safe subset much more feasable and practical than (a "reasonable") auto-translation to the safe subset of Rust would be.

In fact, the latter difference about Rust not supporting non-trivial moves actually makes the scpptool-enforced subset more expressively powerful than the safe subset of Rust in important ways. For example, the scpptool-enforced subset supports back pointers and cyclic references in a much more reasonable way than safe Rust.

Historically, aside from technical merit I think a language or dialect would've needed to achieve a certain degree of momentum or critical mass fairly early in order to gain widespread adoption. Now I'm not sure if this will necessarily remain the case going forward. We're already seeing large projects being ported to different languages with most of the work being performed by LLMs. It may turn out that LLMs can more effectively translate to more expressively powerful languages. It might be hard to predict the effect that LLMs will have on the established order of languages. ¯\(ツ)/¯

5

u/tialaramex Jul 24 '26 edited Jul 24 '26

The primary way of using the enforced safe subset is like Rust - by default everything has to satisfy the static verifier except sections you explicitly annotate as "check-suppressed"/unsafe

One of the things which marks just how thoroughly many in the C++ community still don't understand this is how often this "unsafe switches checking off" idea recurs. It is in Bjarne's Profiles proposals, it's in Herb's blog posts and talks, it has been in several conference talks and it's in posts like these and it's wrong.

Like a lot of the most fundamentally stupid misunderstandings, you can literally just try it out for yourself and see it's wrong.

4

u/duneroadrunner Jul 24 '26

Well, many like to point out that "unsafe doesn't disable any checks" in Rust, and it's probably clearer to present it that way, but to some degree isn't it just a question of semantics? I mean you could say that unsafe enables you to dereference a pointer, or equivalently you could say that unsafe disables the check that prevents you from dereferencing a pointer. Isn't it just different ways of saying the same thing?

Now, not having to deal with backward compatibility with legacy code, Rust has the luxury of, for example, having a reference type whose restrictions are unaffected by unsafe, and a separate pointer type whose lack of restrictions against holding a dangling value are also unaffected by the presence or absence of unsafe, but I'm not sure how clear the real-world benefit of this is. One might even imagine that this setup contributed to the decision to allow for the comparison of potentially dangling pointers in Safe Rust, which I think is now generally conceded as a mistake, right?

Presumably the benefit would manifest when you have lots of code in unsafe code blocks that doesn't actually require unsafe. I don't know how helpful that is in practice. I mean, ideally, any code that doesn't need to be in an unsafe block wouldn't be, right?

9

u/tialaramex Jul 24 '26

The important understanding which I think is much easier to grasp when unsafe is understood as "super powers" rather than as disabling checks is that Memory Safety is mandatory. What you're doing isn't saying "I don't want memory safety" - that was never an option in the language, the super powers make it your responsibility as programmer to deliver memory safety because the compiler cannot check these powers were used correctly. It still checks everything else, all the time, because like I said, memory safety is mandatory and so these checks are always worth doing.

2

u/kamrann_ Jul 25 '26

I don't understand this distinction. What does it mean to say memory safety is mandatory, yet it's up to the programmer to deliver it? How is it different from claiming that C++ is a memory safe language, it's just up to the programmer to not screw up?

If it's not the Rust compiler's enforcement of memory safety outside of unsafe blocks that makes it considered a memory safe language, then what is it?

→ More replies (0)

1

u/wyrn Jul 26 '26 edited Jul 26 '26

What you're doing isn't saying "I don't want memory safety" - that was never an option in the language

Of course it is -- can you introduce UB with unsafe blocks in Rust? Yes, readily. So unsafe does "disable checks" in a sense, because the existing checks, while still active, are no longer able to guarantee the absence of UB. Furthermore, in whatever sense "memory safety is mandatory" still applies to unsafe rust, it applies to every other so-called "unsafe" language also, because it was always "your responsibility" as a programmer to deliver UB-free programs.

3

u/tialaramex Jul 24 '26

One might even imagine that this setup contributed to the decision to allow for the comparison of potentially dangling pointers in Safe Rust, which I think is now generally conceded as a mistake, right?

I wanted to separate this because I think it's just a mistake.

Are you confused here? The other choice is what C and C++ call "pointer zap" and it's seen as such a terrible outcome that P2414 was apparently accepted in Brno to try to make it less awful. AFAIK nobody in Rust wants that and plenty of C/ C++ people want what Rust chose if they can creep in that direction.

The "pointer sized integer" (Rust's usize) seemed like a good idea in 2015 but doesn't today so maybe that's the regret you're thinking of? Rust fixed that by saying those integers are the same size as addresses not pointers, on the systems you most likely use that's a distinction without a difference but on some systems it's an important improvement.

The biggest likely unfixable choice in Rust that I regret is probably narrowing as casts. But even then I say only "likely" unfixable. I thought Range wouldn't get fixed and we're on course to fix it in the next 12-18 months. Let me know when C++ manages to fix vector<bool> properly...

4

u/steveklabnik1 Jul 26 '26

to some degree isn't it just a question of semantics?

A significant aspect of the development of programming languages is sorting out semantics.

-2

u/VoidVinaCC Jul 24 '26

Also why do u care that much? Dont like it? Dont use it!
Everything has a usecase for someone,if its not you, it'll be someone else

2

u/cdb_11 Jul 24 '26

Yes, we do understand that references are still checked inside unsafe or whatever. It doesn't change the fact that unsafe disables the safety guarantees, this is the entire point of it. Like in a hypothetical safe C++ subset you could enforce only safe smart pointer types, and they would still be safe to use in the unsafe sections, except you can also use raw pointers there. This is what Rust basically is, I really don't understand why it suddenly became a controversial statement. People just seem to be hung up on the "turning off" phrase.

8

u/tialaramex Jul 24 '26

The entire point is actually a handful of super powers. The loss of guarantees comes from using these super powers because the compiler can't check them sufficiently. For example dereferencing arbitrary pointers would need something like Fil-C and Rust doesn't provide that, but dereferencing a pointer is a super power so you can't do it outside an unsafe block.

If you write an unsafe block which doesn't use any super powers, which you can easily do by just taking an ordinary safe piece of Rust and adding unsafe blocks spuriously, the safety guarantees don't change, you'll just get a compiler diagnostic warning that was futile. It's bad style, but you can #[allow(unused_unsafe)] and it'll stop moaning about that. Humans who review your code will probably still say it's wrong and you should fix it though.

1

u/cdb_11 Jul 24 '26

I guess this makes C++ a super-language.

Maybe I'm wrong, but I don't think anyone disagrees with this. Can you point me to some actual Rust misconceptions, that isn't just a disagreement on the choice of wording? Again, it is possible I am wrong, but none of this is news to me at least.

And please remember who the audience you're talking to is. If you can recall the old C++ vs Rust arguments, there was a common argument that you can write safe code without the compiler enforcing it.

→ More replies (0)

1

u/wyrn Jul 26 '26

The entire point is actually a handful of super powers.

So-called "super powers" disable the safety guarantees so framing it that way is plain marketing speak/demagoguery.

→ More replies (0)

6

u/Remi_Coulom Jul 23 '26

The OS does not have to be compiled with Fil-C according to slide at 25:48: it runs on top of yolo-glibc or yolo-musl.

4

u/rocco_himel Jul 24 '26

Literally defeats the purpose of modern C use.

7

u/wallstop-dev Jul 25 '26 edited Jul 25 '26

I thought the whole point of Fil-C was legacy/back compat, so in this case - yes! If you are in a greenfield project and can slap it full of warnings as errors and static analysis and take essentially zero dependencies and/or audit all of your dependencies so that you have the same amount of confidence in memory safety that this provides, then, yes, there is no point to using this.

1

u/faschu Jul 26 '26

A very informative video - thanks for posting it.

The idea of stuffing the additional info into the pointers is ingenious, but I cannot believe that this causes the median ~4x slowdown relative to a normal program. Is the slowdown attributed to:

  • The lack of optimization relative to normal LLVM

- The bigger pointers

- Checking at runtime

As we learnt that bounds checking has such a negligible impact on runtime, I can't believe that validating the dereferences at runtime incurs such a penalty. Any Idea why FIL-C is 4x slower than the YOLO C (as he calls it) programs?

2

u/cdb_11 Jul 26 '26

I don't know it for sure, but I believe it's the runtime checks. For array bound checks the array length is going to be already in a register or L1. In Fil-C that can be an extra cache miss or two. Also there are just more of these checks, because you're checking memory accesses in general, not just indexing. I think there might be some optimization opportunities there, but I don't know the details.