Hi, Bill,

Thanks for your new proposal. 

If I understand correctly, this new proposal basically is back to one of our 
previous proposal:

Adding a new structure scoping for counted_by attribute into C;

With this approach, there is one new structure scoping added to C, and this new 
scope 
will shadow other scopes in the current  C. 

The identifiers inside the counted_by attribute will be looked up within this 
new structure scope first.
Conflicted local or global variables need to be prefixed with special builtin 
to explicitly specify its scope.

Is this understanding correctly?

My opinion on this:

1. Personally, as I mentioned multiple times, I think that this might be the 
cleanest solution;
    If other people agree on this, I am happy to go with this.  -:)

2. However, my understanding from our previous long discussion is: 
   Adding a new structure scope to C (even it’s only for counted_by attribute) 
should not be done without
   Having a clear specification and support from WG14.

Please refer to the following:

https://gcc.gnu.org/pipermail/gcc-patches/2025-April/679922.html.
https://gcc.gnu.org/pipermail/gcc-patches/2025-April/679923.html. 

Martin and Joseph, what’s your opinion on this proposal?

Thanks.

Qing
> On Apr 14, 2025, at 13:12, Bill Wendling <isanb...@gmail.com> wrote:
> 
> Soooo....After being on a mini-vacation and thinking about this more,
> I'm a bit less satisfied with the current proposal. The main issue is
> that we have seemingly two lookup rules based on which attribute is
> used (counted_by vs. counted_by_expr).
> 
>  1. counted_by: We expect an expression that's a lone identifier.
> Here, we use a pseudo-struct scope to resolve that identifier.
> ("Pseudo" because it's not fully defined in the standard but created
> for this feature alone.)
> 
>  2. counted_by_expr: Any identifiers that appear in the struct need
> to be forward declared. If they aren't, the normal lookup rules apply.
> 
> Now, I don't think this will be necessarily confusing to the
> programmer, but it's inconsistent. In other words, either 'counted_by'
> *must* forward declare the in-structure identifier or neither must.
> 
> It's also probable that most expressions will use in-structure
> identifiers, with the occasional enum or macro. (I'm going off of
> Yeoul's assertion that they've implemented this successfully on large
> code bases and haven't had to make allowances for global identifiers.)
> 
> My counter proposal then is to do something like this:
> 
> 1. The syntax needs to be unambiguous.
> 2. Identifier lookup must be consistent between the two attribute forms.
> 3. The common use case should take the least amount of code to write.
> (More of a "nice to have".)
> 
> Therefore, I suggest the following rules, that are more-or-less the
> reverse of the current proposal's rules:
> 
> - All untagged identifiers are assumed to be within the structure. If
> they aren't found in the struct, it's an error.
> - All globals (i.e. identifiers not in the struct) must be referenced
> via a special tag or a builtin (e.g. __builtin_global_ref()). The tag
> or builtin follow current scoping rules---i.e. it may pick up a shadow
> variable rather than the global.
> 
> Examples:
> 
> [Assume a builtin called '__builtin_global_ref' that takes an
> expression where every identifier within that expression is assumed
> "global".]
> 
> struct A {
>  int *buf __counted_by(len); // 'len' *must* be in the struct.
>  int len;
> };
> 
> constexpr int len = 42;
> struct B {
>  int *buf __counted_by(__builtin_global_ref(len)); // 'len' is a global.
> };
> 
> enum { PADDING = 42 };
> struct C {
>  int *buf __counted_by_expr(len * __builtin_global_ref(PADDING));
>  int len;
> };
> 
> #define PADDING_EXPR __builtin_gloal_ref(len) + 42
> struct D {
>  int *buf __counted_by_expr(len * PADDING_EXPR);
>    // PADDING_EXPR is expanded and that 'len' is not in the structure.
>  int len;
> };
> 
> #define PADDING_EXPR len + 42
> struct E {
>  int *buf __counted_by_expr(len * __builtin_global_ref(PADDING_EXPR));
>    // PADDING_EXPR is expanded and that 'len' is not in the structure.
>  int len;
> };
> 
> There is the issue that the __builtin_global_ref() in 'struct E' may
> appear to cause the sub-expression to have a higher affinity than the
> multiplication but it doesn't. That may or may not be a programmer
> error, but one to be aware of nonetheless.
> 
> -bw

Reply via email to