Am Donnerstag, dem 13.03.2025 um 15:41 +0000 schrieb Qing Zhao:
> 
> > On Mar 12, 2025, at 12:40, Martin Uecker <uec...@tugraz.at> wrote:
> > 
> > Am Mittwoch, dem 12.03.2025 um 16:20 +0000 schrieb Qing Zhao:
> > > 
> > > > On Mar 10, 2025, at 15:34, Martin Uecker <uec...@tugraz.at> wrote:
> > > > 
> > > > Am Montag, dem 10.03.2025 um 15:00 -0400 schrieb John McCall:
> > > > > 
> > > > 
> > > > ...
> > > > 
> > > > > That said, my preference is still to just give preference to the 
> > > > > field name,
> > > > > which sidesteps any need for disambiguation syntax and avoids this 
> > > > > whole
> > > > > problem where structs can be broken by just adding a global variable 
> > > > > that
> > > > > happens to collide with a field.
> > > > 
> > > > I don't think it is a good idea when the 'n' in 'buf' refers to the
> > > > previous global 'n' coming before and the 'n' in attribute 
> > > > refers to a member 'n' coming later in the following example.
> > > > 
> > > > constexpr int n = 1;
> > > > 
> > > > struct foo {
> > > > char *p [[gnu::counted_by(n)]];
> > > > char buf[n];
> > > > int n;
> > > > };
> > > > 
> > > > How are you going to explain this to anyone?
> > > > 
> > > > 
> > > > And neither global names nor struct members may always be under
> > > > the control of the programmer.  Also that simply bringing
> > > > a new identifier into scope can break code elsewhere worries me.
> > > > 
> > > > 
> > > > Finally, the following does not even compile in C++.
> > > > 
> > > > struct foo {
> > > > char buf[n];
> > > > const static int n = 2;
> > > > };
> > > > 
> > > > While the next example is also ok in C++.
> > > > 
> > > > constexpr int n = 2;
> > > > 
> > > > struct foo {
> > > > char buf[n];
> > > > };
> > > > 
> > > > With both declarations of 'n' the example has UB in C++. 
> > > > So I am not convinced the proposed rules make a lot
> > > > of sense for C++ either.
> > > > 
> > > > 
> > > > Disambiguation with '__self__.'  completely avoids all these issues
> > > > while keeping the door open for later improvements.  
> > > > 
> > > > I still think one could use designator syntax, i.e. '.n', which
> > > > would be clearer and intuitive for both C and C++ programmers.
> > > 
> > > I think the major reason to use __self.n instead of .n is:
> > > 
> > > The dot (.) operator, i.e., the member access operator in C, is used to 
> > > access the member of an _instance_ of 
> > > a structure/union.
> > > We should declare a variable with a structure type first, and then append 
> > > this member access operator to this 
> > > variable and followed by the member name to access the member, and then 
> > > use it in the expressions.
> > 
> > For a designator
> > 
> > struct foo { int n; } a = { .n = 1 };
> > 
> > we also refer to a member 'n' of an instance 'a' of a structure type.
> > The instance is simply implied by the context.
> > 
> > For 
> > 
> > struct foo { int n; char *x __counted_by(.n) };
> > 
> > is also refers to a member of an instance of the struct. The
> > instance is the 'a' which is later used in an expression 'a.x'
> > So the instance would again be implied by the context.
> > 
> > So for me this makes perfect sense in both cases (and
> > for both C and C++)
> 
> Why does ‘.n' also make sense in C++?

For my perspective, it makes sense because C++ also already
uses this syntax of designators, so this syntax should already be
familiar to C++ programmers just like it is for C programmers: 
https://godbolt.org/z/7saEofhEb

It would also disambiguate the name lookup just as it does in C.

So it seems to be a possible way forward while avoiding
language divergence and without introducing anything too novel
in either language.

(But others still have concerns about .n and prefer __self__.)

Martin



Reply via email to