Am Dienstag, dem 25.07.2023 um 20:38 +0000 schrieb Yeoul Na via LLVM
Discussion Forums:
rapidsna
July 25
uecker:
Yes, it is very unfortunatey that somebody added this without
considering
C language rules.
I do not suggest to changes it if it has existing users, but I
would also not recommend to
create more problems. But this example also shows that it might be
difficult to fix such
problems later… or if it is still possibly to fix for guarded_by
(by adding the new syntax
and deprecating the old) we should consider this.
In any case, I think an incompatibility between “guarded_by” and
“counted_by”
is more acceptable than an incompatibilty between C and C++ or an
incompatibility
between VM-types in C and “counted_by” in C.
Well, it’s not just about guarded_by . In C++, identifiers inside a
class/struct generally refer to members.
I see, but then this is caused by a fundamental incompatibility
between C and C++ and not really related to the new feature at all.
Sorry, I did not realize this.
Then the only way out seems to be to use the a new syntax
if we need something for shared headers.
So, I don’t think it’s subject to change for C++. Here is another
example: Compiler Explorer.
int n = 1;
struct f {
int m {n}; // n
is f::n
, not the global n
.
int n;
};
uecker:
GCC supports the following:
{
int n;
struct foo { char (*buf)[n]; int n; } x;
}
Compiler Explorer
(the warning for the second example will go away with full C23
support)
Hmm, what if the member n comes before buf as shown in the following
example?
{
int n;
struct foo { int n; char (*buf)[n]; } x;
}
This does not matter. In C the members of a struct exist in an
entirely different name space than regular identifiers. So
a C parser would either look up in the member namespace in
a construct like x.n or x->n or it would look it up in the
regular name space and then it refers to the variable n.
So adding ‘.’ for disambiguation would work for C
because the lookup can then happen in the member name
space. This is also what happens for designators
int n;
struct foo { int n; } = { .n = 1 };
where .n refers to the member and in
struct foo { int n; } = { n };
it would refer to the variable.
It sounds like n would still be the variable outside the struct? If
so, this seems to generate a confusion for C++ if it were to support
this. I believe the behavior is actually confusing for many C
programmers as well.
To avoid the confusion and divergence, it would make sense to
consider using a new syntax to refer to a non-member or emitting
diagnostics for name conflicts.
I think we should use a new syntax.
A warning would only work in one direction, i.e. when creating
a naming collision, but not if you accidentally refer to the
wrong one due to a typo.
Martin