Date: Thu, 13 Nov 2025 21:22:11 +0100
On 11/13/25 20:54, Aaron Ballman via Liaison wrote:
> On Thu, Nov 13, 2025 at 2:40 PM Corentin <corentin.jabot_at_[hidden]> wrote:
>>
>> Would it help to make it ill-formed in newer standards ?
>> Implementation would issue a diagnostic - which they want to do anyway - but still compile, so existing code would keep working and be handled in an implementation defined manner.
>> That way we keep existing code working without having to care in the specification or to specify odd edge cases.
>> Short of that we should probably clarify that arguments are expanded and that the program is ill-formed if the expansion is not an identifier.
>
> What I think would help would be to replace the part about discarding
> the tokens with a statement about the tokens being unevaluated
> instead. Once the tokens stop being discarded, they have to be
> semantically valid (because those tokens now *exist* as far as the
> compiler is concerned) and that would make the Clang behavior
> conforming when rejecting the undeclared identifier case while still
> allowing warning diagnostics for providing a second argument at all.
Joseph Myers just told me (elsewhere in this thread) that
#define va_start(list, ...) __builtin_va_start(list)
is intended to be allowed by C23. If that's true, that's the
"preprocessing tokens are discarded" situation. I get it that
people here want another option for a conforming implementation
to be "those preprocessing tokens are not discarded, but the
resulting tokens are unevaluated".
Something like "It is implementation-defined
(or unspecified?) whether the preprocessing tokens
for the second and subsequent arguments are discarded.
If they are not discarded, the resulting tokens are
not potentially-evalutated."
It would be good to know whether those tokens are supposed
to be interpreted in an expression context, or
(say) in a type-only lookup context.
Jens
> ~Aaron
>
>>
>> On Thu, Nov 13, 2025 at 11:01 AM Jonathan Wakely via Liaison <liaison_at_[hidden]> wrote:
>>>
>>>
>>>
>>> On Thu, 13 Nov 2025 at 13:18, Aaron Ballman <aaron_at_[hidden]> wrote:
>>>>
>>>> Responding to two separate threads below.
>>>>
>>>> On Wed, Nov 12, 2025 at 3:02 PM Jonathan Wakely <cxx_at_[hidden]> wrote:
>>>>> As I understand it, the whole point of the current specs is to allow implementers to have freedom to provide helpful diagnostics if they choose to. You seem to be saying "don't let me decide what helps my users, force me to implement a particular behaviour".
>>>>
>>>> Not really, no.
>>>>
>>>> The intent from WG14 (AIUI) was that we should continue to accept code
>>>> that was correct in previous versions of C and start accepting only a
>>>> single argument of va_list type, and nothing else. I think the C
>>>> wording is close to capturing that intent, but it's not fully clear
>>>> whether Clang is acting in a non-conforming manner here (in C) by
>>>> rejecting this code which GCC accepts: https://godbolt.org/z/zq6jnqedM
>>>> What I'm gathering from this discussion is that both Clang and GCC's
>>>> behavior is conforming,
>>>>
>>>> I do not think the C++ wording matches the intent from C because it
>>>> explicitly discards all tokens. I'd like to see the two standards
>>>> agree on the behavior here, and I think the tokens should be expanded
>>>> and not discarded because discarding the tokens leads to a specified
>>>> behavior for code which I think should be ill-formed in C++;
>>>> basically, I think Clang's behavior on the example above should apply
>>>> in C++ but per the current wording, Clang is non-conforming. The
>>>> changes LWG made in https://cplusplus.github.io/LWG/issue4388 don't
>>>> quite accomplish what I was hoping for. The new words say "and any of
>>>> the second or subsequent arguments expands to include" but the old
>>>> words "The preprocessing tokens comprising the second and subsequent
>>>> arguments to va_start (if any) are discarded." still remain.
>>>
>>>
>>> That was very much intentional.
>>>
>>> The change is to say that certain misuses are ill-formed; no diagnostic required. There was no intention to also change it to not discard the tokens. We just don't want to imply that discarding the tokens means that it's somehow OK to use unmatched parentheses or completely invalid tokens there, and expect compilers to handle that somehow and make the program well-formed.
>>>
>>>
>>>
>>>>
>>>> So I read
>>>> that as requiring us to expand __COUNTER__ which would increment it,
>>>> but it also requires us to not reject code from my linked example
>>>> because the resulting expanded tokens are discarded. I think it should
>>>> say the (non-preprocessing) tokens are not evaluated.
>>>
>>>
>>> I still find it extremely hard to care about anybody dumb enough to do *anything* in the second argument to va_start. We've already spent more time on these corner cases than any users will ever spend being confused or upset by this aspect of va_start.
>>>
>>> If you warn about anything except an identifier as the second argument, is that good enough? If the code doesn't compile at all in C17 or C++20, and gets a warning diagnostic for later standards, then does it really matter whether it's ill-formed in later standards? If __COUNTER__ is bumped, or not, doesn't seem like a big deal. It's dumb code anyway.
>>>
>>>
>>>>
>>>>
>>>> On Wed, Nov 12, 2025 at 4:12 PM Jens Maurer <jens.maurer_at_[hidden]> wrote:
>>>>> I was trying to tell you earlier that I don't believe C++ had any "intent"
>>>>> of its own in that area, whatever the current wording outcome is.
>>>>
>>>> Sorry for missing that, that's good to know!
>>>>
>>>>> But I do find the C23 wording unclear. It says
>>>>>
>>>>> "Additional arguments beyond the first given to the va_start macro may be expanded and used
>>>>> in unspecified contexts where they are unevaluated."
>>>>>
>>>>> That's a normative permission ("may") in a "Recommended practice" paragraph.
>>>>> That feels like a category error.
>>>>
>>>> I also find the C wording unclear, beyond the category error. There's
>>>> no recommendation there; it just says "for example, an implementation
>>>> ...". I think a plausible repair to C's wording would be to move
>>>> "additional arguments beyond the first" up to the Description section
>>>> so it's more clearly a normative permission, and "For example, an
>>>> implementation" should be reworded to something more along the lines
>>>> of "It is recommended that an implementation..." so it's clear that
>>>> there's a recommendation for producing a diagnostic.
>>>>
>>>> ~Aaron
>>>
>>> _______________________________________________
>>> Liaison mailing list
>>> Liaison_at_[hidden]
>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
>>> Link to this post: http://lists.isocpp.org/liaison/2025/11/1609.php
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> Link to this post: http://lists.isocpp.org/liaison/2025/11/1612.php
> On Thu, Nov 13, 2025 at 2:40 PM Corentin <corentin.jabot_at_[hidden]> wrote:
>>
>> Would it help to make it ill-formed in newer standards ?
>> Implementation would issue a diagnostic - which they want to do anyway - but still compile, so existing code would keep working and be handled in an implementation defined manner.
>> That way we keep existing code working without having to care in the specification or to specify odd edge cases.
>> Short of that we should probably clarify that arguments are expanded and that the program is ill-formed if the expansion is not an identifier.
>
> What I think would help would be to replace the part about discarding
> the tokens with a statement about the tokens being unevaluated
> instead. Once the tokens stop being discarded, they have to be
> semantically valid (because those tokens now *exist* as far as the
> compiler is concerned) and that would make the Clang behavior
> conforming when rejecting the undeclared identifier case while still
> allowing warning diagnostics for providing a second argument at all.
Joseph Myers just told me (elsewhere in this thread) that
#define va_start(list, ...) __builtin_va_start(list)
is intended to be allowed by C23. If that's true, that's the
"preprocessing tokens are discarded" situation. I get it that
people here want another option for a conforming implementation
to be "those preprocessing tokens are not discarded, but the
resulting tokens are unevaluated".
Something like "It is implementation-defined
(or unspecified?) whether the preprocessing tokens
for the second and subsequent arguments are discarded.
If they are not discarded, the resulting tokens are
not potentially-evalutated."
It would be good to know whether those tokens are supposed
to be interpreted in an expression context, or
(say) in a type-only lookup context.
Jens
> ~Aaron
>
>>
>> On Thu, Nov 13, 2025 at 11:01 AM Jonathan Wakely via Liaison <liaison_at_[hidden]> wrote:
>>>
>>>
>>>
>>> On Thu, 13 Nov 2025 at 13:18, Aaron Ballman <aaron_at_[hidden]> wrote:
>>>>
>>>> Responding to two separate threads below.
>>>>
>>>> On Wed, Nov 12, 2025 at 3:02 PM Jonathan Wakely <cxx_at_[hidden]> wrote:
>>>>> As I understand it, the whole point of the current specs is to allow implementers to have freedom to provide helpful diagnostics if they choose to. You seem to be saying "don't let me decide what helps my users, force me to implement a particular behaviour".
>>>>
>>>> Not really, no.
>>>>
>>>> The intent from WG14 (AIUI) was that we should continue to accept code
>>>> that was correct in previous versions of C and start accepting only a
>>>> single argument of va_list type, and nothing else. I think the C
>>>> wording is close to capturing that intent, but it's not fully clear
>>>> whether Clang is acting in a non-conforming manner here (in C) by
>>>> rejecting this code which GCC accepts: https://godbolt.org/z/zq6jnqedM
>>>> What I'm gathering from this discussion is that both Clang and GCC's
>>>> behavior is conforming,
>>>>
>>>> I do not think the C++ wording matches the intent from C because it
>>>> explicitly discards all tokens. I'd like to see the two standards
>>>> agree on the behavior here, and I think the tokens should be expanded
>>>> and not discarded because discarding the tokens leads to a specified
>>>> behavior for code which I think should be ill-formed in C++;
>>>> basically, I think Clang's behavior on the example above should apply
>>>> in C++ but per the current wording, Clang is non-conforming. The
>>>> changes LWG made in https://cplusplus.github.io/LWG/issue4388 don't
>>>> quite accomplish what I was hoping for. The new words say "and any of
>>>> the second or subsequent arguments expands to include" but the old
>>>> words "The preprocessing tokens comprising the second and subsequent
>>>> arguments to va_start (if any) are discarded." still remain.
>>>
>>>
>>> That was very much intentional.
>>>
>>> The change is to say that certain misuses are ill-formed; no diagnostic required. There was no intention to also change it to not discard the tokens. We just don't want to imply that discarding the tokens means that it's somehow OK to use unmatched parentheses or completely invalid tokens there, and expect compilers to handle that somehow and make the program well-formed.
>>>
>>>
>>>
>>>>
>>>> So I read
>>>> that as requiring us to expand __COUNTER__ which would increment it,
>>>> but it also requires us to not reject code from my linked example
>>>> because the resulting expanded tokens are discarded. I think it should
>>>> say the (non-preprocessing) tokens are not evaluated.
>>>
>>>
>>> I still find it extremely hard to care about anybody dumb enough to do *anything* in the second argument to va_start. We've already spent more time on these corner cases than any users will ever spend being confused or upset by this aspect of va_start.
>>>
>>> If you warn about anything except an identifier as the second argument, is that good enough? If the code doesn't compile at all in C17 or C++20, and gets a warning diagnostic for later standards, then does it really matter whether it's ill-formed in later standards? If __COUNTER__ is bumped, or not, doesn't seem like a big deal. It's dumb code anyway.
>>>
>>>
>>>>
>>>>
>>>> On Wed, Nov 12, 2025 at 4:12 PM Jens Maurer <jens.maurer_at_[hidden]> wrote:
>>>>> I was trying to tell you earlier that I don't believe C++ had any "intent"
>>>>> of its own in that area, whatever the current wording outcome is.
>>>>
>>>> Sorry for missing that, that's good to know!
>>>>
>>>>> But I do find the C23 wording unclear. It says
>>>>>
>>>>> "Additional arguments beyond the first given to the va_start macro may be expanded and used
>>>>> in unspecified contexts where they are unevaluated."
>>>>>
>>>>> That's a normative permission ("may") in a "Recommended practice" paragraph.
>>>>> That feels like a category error.
>>>>
>>>> I also find the C wording unclear, beyond the category error. There's
>>>> no recommendation there; it just says "for example, an implementation
>>>> ...". I think a plausible repair to C's wording would be to move
>>>> "additional arguments beyond the first" up to the Description section
>>>> so it's more clearly a normative permission, and "For example, an
>>>> implementation" should be reworded to something more along the lines
>>>> of "It is recommended that an implementation..." so it's clear that
>>>> there's a recommendation for producing a diagnostic.
>>>>
>>>> ~Aaron
>>>
>>> _______________________________________________
>>> Liaison mailing list
>>> Liaison_at_[hidden]
>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
>>> Link to this post: http://lists.isocpp.org/liaison/2025/11/1609.php
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> Link to this post: http://lists.isocpp.org/liaison/2025/11/1612.php
Received on 2025-11-13 20:22:19
