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