Re: C aggregate passing (Rust kernel policy)

Ventura Jack
2025-02-27T19:07:06Z

On Thu, Feb 27, 2025 at 10:58 AM Ralf Jung <post@ralfj.de> wrote:
> >> https://godbolt.org/z/rjaWc6EzG
> >
> > That example uses a compiler-specific attribute AFAIK, namely
> >
> > __attribute__((noinline))
> >
> > When using compiler-specific attributes and options, the
> > original language is arguably no longer being used, depending
> > on the attribute. Though a language being inexpressive and
> > possibly requiring compiler extensions to achieve some goals,
> > possibly like in this C example, can be a disadvantage in itself.
>
> That attribute just exists to make the example small and fit in a single file.
> If you user multiple translation units, you can achieve the same effect without
> the attribute. Anyway compilers promise (I hope^^) that that particular
> attribute has no bearing on whether the code has UB. So, the question of whether
> the program without the attribute has UB is still a very interesting one.
>
> At least clang treats this code as having UB, and one can construct a similar
> example for gcc. IMO this is not backed by the standard itself, though it can be
> considered backed by some defect reports -- but those were for earlier versions
> of the standard so technically, they do not apply to C23.

That is fair. For C++26, I suspect that the behavior will actually
be officially defined as "erroneous behavior". For C, it is very
unfortunate if the compilers are more strict than the standard
in this case.

I wonder why if that is the case here. C and C++ (also before C++26)
differ on that subject. The differences between C and C++ have
likely caused bugs and issues for both compilers and users.
Though the cause could also be something else.

I am surprised that the C standard is lax on this point in some
cases. It is related to values that are or are not trap representations/
non-value representations, and variables that could or could
not be registers, as I understand one explanation I found.

> > Rust is more willing to break existing code in projects, causing
> > previously compiling projects to no longer compile. rustc does this
> > rarely, but it has happened, also long after Rust 1.0.
> >
> > From last year, 2024.
> >
> > https://internals.rust-lang.org/t/type-inference-breakage-in-1-80-has-not-been-handled-well/21374
> > "Rust 1.80 broke builds of almost all versions of the
> > very popular time crate (edit: please don't shoot the
> > messenger in that GitHub thread!!!)
> >
> > Rust has left only a 4-month old version working.
> > That was not enough time for the entire Rust
> > ecosystem to update, especially that older
> > versions of time were not yanked, and users
> > had no advance warning that it will stop working.
> >
> > A crater run found a regression in over 5000 crates,
> > and that has just been accepted as okay without
> > any further action! This is below the level of stability
> > and reliability that Rust should have."
> >
> > If C was willing to break code as much as Rust, it would be easier to
> > clean up C.
>
> Is that true? Gcc updates do break code.

Surely not as much as Rust, right? From what I hear from users
of Rust and of C, some Rust developers complain about
Rust breaking a lot and being unstable, while I instead
hear complaints about C and C++ being unwilling to break
compatibility.

Rust does admittedly a lot of the time have tools to
mitigate it, but Rust sometimes go beyond that.
C code from 20 years ago can often be compiled
without modification on a new compiler, that is a common
experience I hear about. While I do not know if that
would hold true for Rust code. Though Rust has editions.
The time crate breaking example above does not
seem nice.

> > A fear I have is that there may be hidden reliance in
> > multiple different ways on LLVM, as well as on rustc.
> > Maybe even very deeply so. The complexity of Rust's
> > type system and rustc's type system checking makes
> > me more worried about this point. If there are hidden
> > elements, they may turn out to be very difficult to fix,
> > especially if they are discovered to be fundamental.
> > While having one compiler can be an advantage in
> > some ways, it can arguably be a disadvantage
> > in some other ways, as you acknowledge as well
> > if I understand you correctly.
>
> The Rust type system has absolutely nothing to do with LLVM. Those are
> completely separate parts of the compiler. So I don't see any way that LLVM
> could possibly influence our type system.

Sorry for the ambiguity, I packed too much different
information into the same block.

> > You mention ossifying, but the more popular Rust becomes,
> > the more painful breakage will be, and the less suited
> > Rust will be as a research language.
>
> I do not consider Rust a research language. :)

It reminds me of Scala, in some ways, and some complained
about Scala having too much of a research and experimental
focus. I have heard similar complaints about Rust being
too experimental, and that was part of why they did not
wish to adopt it in some organizations. On the other hand,
Amazon Web Services and other companies already
use Rust extensively. AWS might have more than 300
Rust developer employed. The more usage and code,
the more painful breaking changes might be.

> > I hope that any new language at least has its
> > language developers ensure that they have a type
> > system that is formalized and proven correct
> > before that langauge's 1.0 release.
> > Since fixing a type system later can be difficult or
> > practically impossible. A complex type system
> > and complex type checking can be a larger risk in this
> > regard relative to a simple type system and simple
> > type checking, especially the more time passes and
> > the more the language is used and have code
> > written in it, making it more difficult to fix the language
> > due to code breakage costing more.
>
> Uff, that's a very high bar to pass.^^ I think there's maybe two languages ever
> that meet this bar? SML and wasm.

You may be right about the bar being too high.
I would have hoped that it would be easier to achieve
with modern programming language research and
advances.

> >>> There are some issues in Rust that I am curious as to
> >>> your views on. rustc or the Rust language has some type
> >>> system holes, which still causes problems for rustc and
> >>> their developers.
> >>>
> >>> https://github.com/lcnr/solver-woes/issues/1
> >>> https://github.com/rust-lang/rust/issues/75992
> >>>
> >>> Those kinds of issues seem difficult to solve.
> >>>
> >>> In your opinion, is it accurate to say that the Rust language
> >>> developers are working on a new type system for
> >>> Rust-the-language and a new solver for rustc, and that
> >>> they are trying to make the new type system and new solver
> >>> as backwards compatible as possible?
> >>
> >> It's not really a new type system. It's a new implementation for the same type
> >> system. But yes there is work on a new "solver" (that I am not involved in) that
> >> should finally fix some of the long-standing type system bugs. Specifically,
> >> this is a "trait solver", i.e. it is the component responsible for dealing with
> >> trait constraints. Due to some unfortunate corner-case behaviors of the old,
> >> organically grown solver, it's very hard to do this in a backwards-compatible
> >> way, but we have infrastructure for extensive ecosystem-wide testing to judge
> >> the consequences of any given potential breaking change and ensure that almost
> >> all existing code keeps working. In fact, Rust 1.84 already started using the
> >> new solver for some things
> >> (https://blog.rust-lang.org/2025/01/09/Rust-1.84.0.html) -- did you notice?
> >> Hopefully not. :)
> >
> > If it is not a new type system, why then do they talk about
> > backwards compatibility for existing Rust projects?
>
> If you make a tiny change to a type system, is it a "new type system"? "new type
> system" sounds like "from-scratch redesign". That's not what happens.

I can see your point, but a different type system would be
different. It may be a matter of definition. In practice, the
significance and consequences would arguably depend on
how much backwards compatibility it has, and how many and
how much existing projects are broken.

So far, it appears to require a lot of work and effort for
some of the Rust language developers, and my impression
at a glance is that they have significant expertise, yet have
worked on it for years.

Best, VJ.