Am Dienstag, dem 01.04.2025 um 17:13 -0700 schrieb Bill Wendling: > On Tue, Apr 1, 2025 at 8:29 AM Martin Uecker <uec...@tugraz.at> wrote: > > Am Dienstag, dem 01.04.2025 um 15:01 +0000 schrieb Qing Zhao: > > > > On Apr 1, 2025, at 10:04, Martin Uecker <uec...@tugraz.at> 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