C++ Logo

liaison

Advanced search

Re: [isocpp-wg14/wg21-liaison] Extra arguments to va_start

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Thu, 13 Nov 2025 21:33:31 +0000
On Thu, 13 Nov 2025 at 21:06, Joshua Berne via Liaison <
liaison_at_[hidden]> wrote:

> Rather than make up "here's how valid they have to be", Corentin's
> suggestion of ill-formed (or ifndr, or unspeciformed, if we want) seems
> like an improvement to me.
>

That seems drastic though. It means all valid C17 and C++23 code that uses
va_start "correctly" would now be ill-formed. It might still compile after
issuing a diagnostic, but that doesn't help anybody who uses -Werror or who
cares about not hitting "ill-formed, no diagnostic required", which might
as well be "your valid C++23 code how has undefined behaviour".

Why would that be better than "it might be ignored, or it might not"?
Because it would be portably bad, for every user of va_start?



> On Thu, Nov 13, 2025 at 3:22 PM Jens Maurer via Liaison <
> liaison_at_[hidden]> wrote:
>
>>
>>
>> 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
>>
>> _______________________________________________
>> 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/1614.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/1615.php
>

Received on 2025-11-13 21:33:50