Am Dienstag, dem 21.07.2026 um 12:06 +0200 schrieb Arsen Arsenović:
> Sorry, this email slipped by my inbox.
> 
> Martin Uecker <[email protected]> writes:
> 
> > Am Samstag, dem 09.05.2026 um 11:08 +0200 schrieb Arsen Arsenović:
> > > Martin Uecker <[email protected]> writes:
> > > 
> > > > What I find unlucky, for example, is that we do have a generic
> > > > tree data structure with a lot of imlicit assumptions and lot
> > > > of issues if those are violated. So encapsulating this properly
> > > > in abstract data types would be really helpful.  But we could do
> > > > this also in C, while the switch to C++ apparently did nothing
> > > > to address this.
> > > 
> > > Indeed, adding '-x c++' doesn't automatically fix existing code.
> > > 
> > > However, C++ enables other things to be done here.  For instance, at
> > > one of the Office Hours, a mechanism for encoding tree types (without
> > > requiring rewriting massive amounts of code) was proposed.  It relied on
> > > templates, and it compiles down to the same code as today, and can
> > > provide a bridge for existing code.  Essentially, it allowed us to
> > > specify types such as 'ttree<one_of<PLUS_EXPR, MINUS_EXPR>>' or such,
> > > and could automatically insert (and elide) gcc_asserts that check for
> > > those tree codes.
> > > 
> > > I don't recall who proposed it or if it ever was sent, but a similar
> > > thing wouldn't be possible in C.
> > 
> > It isn't clear to me what that removing gcc_asserts by a complicated
> > type (that then may be hidden behind "auto" because typing it out
> > is to cumbersome) is necessarily an improvement.
> 
> It is an improvement.

I do not think so. Alone the compile-time cost of templates makes
this a bad trade-off in my opinion, and I find compilation time already
to be problematic for GCC.

I agree that catching errors at compile time is good, but in
many cases this can be achieved in C just as well.  I usually find
that people underestimate what can be done in C alone.  Clearly, C++
allows you to do more sophisticated typing (I wrote for some time
expression-template libraries before I decided that this just takes
too much of my time). Being clever with C++ templates is - in my
experience - usually a bad trade-off as the cost in complexity and
compilation times exceeds the improvements in type safety you can
achieve in this way.

> The former detects errors at runtime, meaning
> necessarily that it can only be performed if a codepath is reached (and,
> what's more, not just if the assert itself is reached, but if the right
> execution path is reached; not all paths that reach a given assert are
> built the same of course).  The latter is a compile time error, meaning
> incorrect paths cannot even be compiled (with the caveat that we'd
> necessarily need to start with gradual typing, which, like typing.Any in
> Python, would still permit *some* possibly incorrect code for
> compatibility sake).
> 
> This exact distinction is the motivating drive between the "typed
> qualifiers"[1] patch series I proposed recently (though, of course, that
> one is a far smaller refactor that took less than a full workday to do
> over the whole codebase after settling on a design, so it didn't need to
> be done gradually like a change to 'tree' would).
> 
> Obviously, that case is far simpler, but that refactor - a miniature and
> much simpler change compared to gradually-typed trees - managed to
> detect dozens of bugs in the C++ FE while I was implementing support for
> named address spaces.
> 
> It was well worth it, and I regret that I didn't do that before
> embarking on implementing NAS support.  My intuition told me to do typed
> qualifiers first (as soon as I started working on NAS support), but I
> figured that I wouldn't have time to do it as part of the project that
> required C++ NAS support.  In the end, delaying typed qualifiers cost
> more time than implementing them.
> 
> I imagine the effects over the larger GCC codebase would be much
> greater.  Though, because my (extremely unfinished) proposal is for the
> introduction of effectually gradual typing, we probably won't see
> extremely confronting immediate effects like with typed qualifiers, but
> it should prevent a number of latent bugs and make code easier to
> understand, and possibly detect bugs if someone was to spend some time
> "propagating" typing through the codebase.
> 
> I'd love to have something to show to demonstrate what I was describing,
> but I haven't had time to implement it yet.  It's not a very easy thing
> to do all things considered.
> 
> > The issue with C++ is that people get overly excited about
> > the impressive capabilities of the language (and don't get me wrong,
> > there was a time in my life where I was too!), and in toy examples
> > this always looks cool,  but then if you look at actual code in
> > a larger project it is often much harder to understand.
> > 
> > What we would need in my opinion would be simply
> > 
> > struct expression;
> > struct type;
> > struct statement;
> > etc.
> > 
> > wrappers aroung tree nodes and a set of helpers function to operate on
> > such data types without breaking their invariants, nothing more and
> > nothing less.
> > 
> > In C FE it looks somebody was starting to introduce such wrappers,
> > but apparently never made a lot of progress. 
> 
> I wasn't proposing something complex in a vacuum or for fun.  I was
> proposing something complex for a case where we have an essentially
> untyped program, namely GCC, which is effectively dynamically typed
> because 'tree' nodes are statically indistinguishable in the C and C++
> type systems, where we should work to introduce static typing.

I agree, but the untypedness of tree is not the fault of C and
changing this would not require switching to C++.  It would simply
require to introduce C types for each specific node type.

Martin

> 
> As experience with TypeScript and MyPy shows in the JavaScript and
> Python ecosystems respectively, this requires a long time and, to be
> feasible at all, requires the introduction of gradual typing constructs.
> 
> Gradual typing obviously doesn't exist in C and C++ OOTB.  However, it
> can be implemented in the latter.
> 
> If we were writing GCC from scratch, having dedicated types instead of a
> single 'tree' and some metaprogramming soup to implement a new type
> system inside the C++ type system would easily be the better choice,
> indeed, but we aren't writing GCC from scratch.
> 
> We have some three million lines of C++ code in GCC proper.  This
> existing codebase frequently relies on patterns permitted by dynamic
> typing, such as passing many different types as a single argument in a
> single overload, sometimes even where they're of entirely different code
> classes.
> 
> We do not have the luxury of picking something simple here.  We cannot
> "just" do that refactor like I could with typed qualifiers.
> 
> Dynamic and gradual typing are the only choices.  The latter is easily
> better.
> 
> On the "problem" of 'auto': the identifier 'tree' carries no semantic
> meaning.  It can be anything.
> 
> Thus, it is strictly worse than 'auto', because 'auto' is a shorthand
> for deduction.  It preserves the type of the value given to it, meaning
> that the compiler, and tooling, like an LSP server for instance, and
> thus editors, or even the user if a compiler diagnostic is emitted,
> indeed do know the type.
> 
> 'tree' erases the type of the value given to it.  Asserting on a 'tree'
> verifies the type in one instant, but that verification is gone at time
> of next def.
> 
> 'auto' is the omission of redundant type information, but not its
> erasure.
> 
> Of course, this redundancy can be useful because 1) the user truly does
> specifically intend to constrain the type, where it matters that
> e.g. they're only dealing with a specific tree_code(_class), or 2) a
> reviewer looking at a patch does not have tooling immediately available
> to them to reveal the type.
> 
> But, this can easily go the other way: if reason (1) isn't why the
> redundancy is made explicit, then this just hinders the ability to
> update some unrelated types in the codebase, because it requires usage
> sites where this change isn't semantically significant to change.  A
> declaration not using 'auto', that does not fall under (1), is
> semantically over-constrained.
> 
> In my experience with codebases that rely heavily on type deduction
> (most often in functional programming languages or in projects using the
> aforementioned JavaScript and Python gradual typing extensions, or even
> C++ codebases that IMO overuse 'auto'), the lack of the redundancy for
> reason (2) is rarely a problem.
> 
> Thus, I advocate for using 'auto' in all cases except for those that
> fall under (1).
> 
> [1] 
> https://inbox.sourceware.org/gcc-patches/[email protected]/

Reply via email to