Hi, Bill, Thanks for the summary.
I think that this is good. Two more questions: 1. Shall we keep the same name of the attribute counted_by for the 2nd new syntax? Or use a new name, such as, “counted_by_exp"? I don’t have strong preference here. As mentioned by Jacub in a previous email, these two syntaxes can be distinguished by the number of arguments of the attribute. So for GCC, there should be no issue with either old name of a new name. However, I am not sure about CLANG. (Considering the complication with APPLE’s implementation) 2. The 2nd new syntax should resolve all the following new requests from Linux Kernel: 2.1 Refer to a field in the nested structure 2.2 Refer to globals or locals 2.3 Represent simple expression 2.4 Forward referencing Except not very sure on 2.1: refer to a field in the nested structure struct Y { int n; int other; } struct Z { struct Y y; int array[] __attribute__ ((counted_by(?y.n))); }; in the above, what should be put instead of "?" to refer to the field "n" of the field "y" of the current object of this struct Z? Based on my understanding, with the new syntax, struct Z { struct Y y; int array[] __attribute__ ((counted_by(struct Y y, y.n))); }; i.e, the compiler will lookup “y” inside the current structure, then resolving the member access operator “.” as an expression. Is this correct understanding? Thanks. Qing > On Apr 2, 2025, at 14:35, Bill Wendling <isanb...@gmail.com> wrote: > > On Tue, Apr 1, 2025 at 11:49 PM Jakub Jelinek <ja...@redhat.com> wrote: >> On Tue, Apr 01, 2025 at 05:13:46PM -0700, Bill Wendling wrote: >>> 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 >> >> There are existing attributes which support general expressions in their >> arguments, e.g. the assume attribute, OpenMP attributes etc. Those >> definitely >> shouldn't change behavior if some new behavior for identifier lookup in >> attributes >> is added. >> Many others do support identifiers as their arguments (e.g. mode attribute, >> 2 argument malloc attribute, ...). Those can't change behavior either. >> >> I think using either a predefined identifier or self-declared one is the >> only reasonable way to go (whether it represents something like this pointer >> in C++ or in the latter case possibly forward declaration of the member), >> otherwise >> it will be hard to understand for users and very much error prone. > > Thanks everyone. Here's an updated version of the proposal. As always, > please correct and / or add your own rationales to these suggestions. > > --- > 1. Identifiers: For a single identifier, use the current syntax, which > works in both GCC and Clang: > > struct foo { > char count; > struct bar { > struct { > int len; > }; > struct { > struct { > int *valid_use __counted_by(len); // Valid. > }; > }; > int *invalid_use __counted_by(count); // Invalid. > } b; > }; > > It currently works and doesn't add any new scoping rules, even minor > ones. Hopefully, this is the least controversial suggestion. :-) > > 2. Expressions: Add forward declarations for fields used in > expressions (other than single identifiers). For example: > > const byte_size = 8; > enum { PADDING = 42, TON_BEAR }; > struct foo { > int count; > int size; > int *buf __counted_by(int count, size; count * size + PADDING * byte_size); > }; > > Variables forward declared inside of the attribute are fields inside > the least enclosing, non-anonymous struct and must have the same type > as those fields. All other identifiers are found outside the struct. > > Rationale: This not only uses current C lookup rules but makes > explicit how each identifier within an expression is meant to be > resolved. Many compilers that aren't able to add new identifier > resolution rules based on non-codified scoping rules, and so this > syntax will allow them to implement this feature. > > Bonus suggestion (by yours truly): > > I still like my idea of using a function pointer, but It might not be > as necessary with option (2). > > --- > > -bw