Re: C aggregate passing (Rust kernel policy)

Linus Torvalds
2025-02-25T21:25:01Z

On Tue, 25 Feb 2025 at 12:55, Kent Overstreet <kent.overstreet@linux.dev> wrote:
>
> The problem isn't that "pointer aliasing is fundamentally unsafe and
> dangerous and therefore the compiler just has to stay away from it
> completely" - the problem has just been the lack of a workable model.

It's not entirely clear that a workable aliasing model exists outside
of "don't assume lack of aliasing".

Because THAT is the only truly workable model I know of. It's the one
we use in the kernel, and it works just fine.

For anything else, we only have clear indications that _unworkable_
models exist.

We know type aliasing is garbage.

We know "restrict" doesn't work very well: part of that is that it's
fairly cumbersome to use, but a large part of that is that a pointer
will be restricted in one context and not another, and it's just
confusing and hard to get right.

That, btw, tends to just generally indicate that any model where you
expect the programmer to tell you the aliasing rule is likely to be
unworkable. Not because it might not be workable from a *compiler*
standpoint (restrict certainly works on that level), but because it's
simply not a realistic model for most programmers.

What we do know works is hard rules based on provenance. All compilers
will happily do sane alias analysis based on "this is a variable that
I created, I know it cannot alias with anything else, because I didn't
expose the address to anything else".

I argued a few years ago that while "restrict" doesn't work in C, what
would have often worked is to instead try to attribute things with
their provenance. People already mark allocator functions, so that
compilers can see "oh, that's a new allocation, I haven't exposed the
result to anything yet, so I know it can't be aliasing anything else
in this context". That was a very natural extension from what C
compilers already do with local on-stack allocations etc.

So *provenance*-based aliasing works, but it only works in contexts
where you can see the provenance. Having some way to express
provenance across functions (and not *just* at allocation time) might
be a good model.

But in the absence of knowledge, and in the absence of
compiler-imposed rules (and "unsafe" is by *definition* that absence),
I think the only rule that works is "don't assume they don't alias".

Some things are simply undecidable. People should accept that. It's
obviously true in a theoretical setting (CS calls it "halting
problem", the rest of the academic world calls it "Gödel's
incompleteness theorem").

But it is even *MORE* true in practice, and I think your "the problem
has just been the lack of a workable model" is naive. It implies there
must be a solution to aliasing issues. And I claim that there is no
"must" there.

Just accept that things alias, and that you might sometimes get
slightly worse code generation. Nobody cares. Have you *looked* at the
kind of code that gets productized?

Linus