On 10 Mar 2025, at 18:30, Martin Uecker wrote:
> Am Montag, dem 10.03.2025 um 16:45 -0400 schrieb John McCall:
>>> On 10 Mar 2025, at 15:34, Martin Uecker 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.
>>>
>>> I agree. I think compilers ought to diagnose this with a warning, and
>>> arguably it should be invalid under the standard. 
>
> The problem is that you want to introduce new rules
> that work differently that what the language currently says.
> A new warning could mitigate the damage, but wouldn't it be 
> better to do something which is unambigous from the
> beginning?
>
> ...
>>>
>>> Fortunately, this sort of thing is largely theoretical in actual code
>>> today. Unfortunately, it is not even slightly theoretical with
>>> bounds-safety attributes.
>>>
>>>>> And neither global names nor struct members may always be under
>>>>> the control of the programmer.
>>>
>>> A programmer adding an attribute to a struct field can certainly
>>> declare a new global constant immediately before the struct.
>
>>>
>>>>> Also that simply bringing
>>>>> a new identifier into scope can break code elsewhere worries me.
>>>
>>> Yes, but this is only a problem if we diagnose an ambiguity. There is
>>> no such problem with just preferring a struct field, unless you’re
>>> equally concerned about shadowing whenever you create a local
>>> variable.
>
> So do you want a warning or not?
>
>>>
>>>>> Finally, the following does not even compile in C++.
>>>>>
>>>>> struct foo {
>>>>>   char buf[n];
>>>>>   const static int n = 2;
>>>>> };
>>>
>>> And I am not suggesting that it should. Anything that would change
>>> the type of a declaration really has to continue to be processed
>>> immediately. But code being invalid does not create inconsistency.
>>> Non-constant array bounds are invalid in structs, but that is not
>>> inconsistent, it’s a limitation in expressivity. What’s important
>>> is that code be consistently interpreted everywhere it is valid.
>
> What is important is not to confuse the programmer with
> inconsistent rules.
>
>>>
>>>>> 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.
>>>
>>> If C required a diagnostic in your first example, it would actually
>>> put a fair amount of pressure on the C++ committee to get rid of
>>> this spurious UB rule.
>
> Why would C want a diagnostic here?

When I said “your first example”, Martin, I did actually mean your
first example:

struct foo {
  char *p [[gnu::counted_by(n)]];
  char buf[n];
  int n;
};

But I think it’s clear that you and I just differ on some basic design
philosophy, so let’s just end the conversation here.

John.

>>>>> I still think one could use designator syntax, i.e. '.n', which
>>>>> would be clearer and intuitive for both C and C++ programmers.
>>>
>>> This doesn’t really solve the ambiguity problem. If n is a field name,
>>> a programmer who writes __counted_by(n) almost certainly means to name
>>> the field. “The proper syntax is .n” is the cause of the bug, not its
>>> solution.
>
> Field names in C are in a different namespace. So far, when you write
> 'n' this *never* refers to field member in any context.  And I have
> never seen anybody request a warning for the examples above. So, no, 
> "a programmer almost certainly means this" can not possible be true.
>
> Martin

Reply via email to