Am Dienstag, dem 01.04.2025 um 17:13 -0700 schrieb Bill Wendling:
> On Tue, Apr 1, 2025 at 8:29 AM Martin Uecker <[email protected]> wrote:
> > Am Dienstag, dem 01.04.2025 um 15:01 +0000 schrieb Qing Zhao:
> > > > On Apr 1, 2025, at 10:04, Martin Uecker <[email protected]> wrote:
> > > > Am Montag, dem 31.03.2025 um 13:59 -0700 schrieb Bill Wendling:
> > > > > > I'd like to offer up this to solve the issues we're facing. This is
> > > > > > a
> > > > > > combination of everything that's been discussed here (or at least
> > > > > > that
> > > > > > I've been able to read in the centi-thread :-).
> > > >
> > > > Thanks! I think this proposal much better as it avoids undue burden
> > > > on parsers, but it does not address all my concerns.
> > > >
> > > >
> > > > From my side, the issue about compromising the scoping rules of C
> > > > is also about unintended non-local effects of code changes. In
> > > > my opinion, a change in a library header elsewhere should not cause
> > > > code in a local scope (which itself might also come from a macro) to
> > > > emit a warning or require a programmer to add a workaround. So I am
> > > > not convinced that adding warnings or a workaround such as
> > > > __builtin_global_ref is a good solution.
>
> To clarify, I'm not in favor of adding a generalized new scoping rule
> to C, but only for identifiers in attributes. From what I've seen in
> the discussions, I think that's what most people have been suggesting.
> This should limit any issues with changes in current code.
If we want something we can standardize later, I think this is
problematic.
> > > > I could see the following as a possible way forward: We only
> > > > allow the following two syntaxes:
> > > >
> > > > 1. Single argument referring to a member.
> > > >
> > > > __counted_by(len)
> > > >
> > > > with an argument that must be a single identifier and where
> > > > the identifier then must refer to a struct member.
> > > >
> > > > (I still think this is not ideal and potentially
> > > > confusing, but in contrast to new scoping rules it is
> > > > at least relatively easily to explain as a special rule.).
>
> I'm wavering on whether it's going to be too confusing. The initial
> design was to use the bare struct member name, so that indicates to me
> that it's maybe a more natural way of referring to the 'count' field
> than not---at least with a single identifier.
>
The single name case would be a natural way if it was
not an exception of the language rules *and* if the same syntax
would not already have a different meaning in almost the same
context. This is the combination which almost certainly guarantees
confusion.
This is where, as a teacher or trainer, you would have to repeatedly
point out: "Attention, here is a special case and it works
differently and even even different to this very similar other
case right next to it."
> As Apple has stated,
> they've had no confusion among their developers with this type of
> identifier usage.
I am missing too much context to really make sense of this
statement, but I would assume Apple has a limited use case where
it was mostly annotating some existing C headers that exist in their
environment.
>
> > > > 2. Forward declarations.
> > > >
> > > > __counted_by(size_t len; len + PADDING)
> > >
> > > In the above, the PADDING is some constant?
> >
> > In principle - when considering only the name lookup rules -
> > it could be a constant, a global variable, or an automatic
> > variable, i.e. any ordinary identifiers which is visible at
> > this point.
> >
> > >
> > > More complicated expressions involving globals will not be supported?
> >
> > I think one could allow such expressions, But I think the
> > expressions should be restricted to expressions which have
> > no side effects.
> >
> > >
> > > > where then the second part can also be a more complicated
> > > > expression, but with the explicit requirement that all
> > > > identifiers in this expression are then looked up according to
> > > > regular C language rules. So except for the forward declared
> > > > member(s) they are *never* looked up in the member namespace of
> > > > the struct, i.e. no new name lookup rules are introduced.
>
> I'm on record as *hating* the idea of using expressions (apart from an
> identifier) in attributes. Having the compiler silently add a "ptr->"
> for every identifier in an expression seems like a hack to me. This is
> the reason I added my proposal for a function pointer to handle
> expressions. Even though I'm in the minority on this, I'd still like
> the option to use function pointers.
The function pointer option has some appealing properties, but
the idea that the compiler synthesizes a function call on each
member lookup still scares me a bit. It is somehow too powerful.
It also makes it more difficult for other tooling to extract
the relevant information, and also more difficult for the human
reader to piece things togetger.
>
> > > One question here:
> > >
> > > What’s the major issue if we’d like to add one new scoping rule, for
> > > example,
> > > “Structure scope” (the same as the C++’s instance scope) to C?
> > >
> > > (In addition to the "VLA in structure" issue I mentioned in my previous
> > > writeup,
> > > is there any other issue to prevent this new scoping rule being added
> > > into C ?).
> >
> > Note that the "VLA in structure" is a bit of a red herring. The exact same
> > issues apply to lookup of any other ordinary identifiers in this context.
> >
> > enum { MY_BUF_SIZE = 100 };
> > struct foo {
> > char buf[MY_BUF_SIZE];
> > };
> >
> >
> > C++ has instance scope for member functions. The rules for C++ are also
> > complex and not very consistent (see the examples I posted earlier,
> > demonstrating UB and compiler divergence). For C such a concept would
> > be new and much less useful, so the trade-off seems unfavorable (in
> > constrast to C++ where it is needed). I also see others issues: Fully
> > supporting instance scope would require changes to how C is parsed,
> > placing a burden on all C compilers and tooling. Depending on how you
> > specify it, it would also cause a change in semantics
> > for existing code, something C tries very hard to avoid. If you add
> > warnings as mitigation, it has the problem that it causes non-local
> > effects where introducing a name in in enclosing scope somewhere else
> > now necessitates a change to unrelated code, exactly what scoping rules
> > are meant to prevent.
>
> As I mentioned above (and alluded to in the original post), I think
> adding full C++ instance scoping to C is a Bad Idea(tm). What we do
> here would be a small subset of what's done in C++ and restricted to
> identifiers in attributes.
What do you think about my compromise proposal (which builds on
yours)?
I also still think designator syntax solves all problem (with a
suitable disambiguation rule for the grammar issue)
__counted_by ( .n + PADDING )
in a nicer way for both C and C++. If we limited the expressions
to certain specific forms, one also could avoid having forward
declarations.
Martin