[PATCH] assert: Support assert as variadic macro for C++26 [PR27276]

Jonathan Wakely jwakely@redhat.com
Thu Feb 5 16:07:06 GMT 2026


On Thu, 5 Feb 2026 at 16:02, Tomasz Kaminski <tkaminsk@redhat.com> wrote:
>
>
>
> On Thu, Feb 5, 2026 at 5:00 PM Jonathan Wakely <jwakely@redhat.com> wrote:
>>
>> On Thu, 5 Feb 2026 at 15:56, Florian Weimer <fweimer@redhat.com> wrote:
>> >
>> > * Jonathan Wakely:
>> >
>> > > On Thu, 5 Feb 2026 at 15:40, Tomasz Kaminski <tkaminsk@redhat.com> wrote:
>> > >>
>> > >>
>> > >>
>> > >> On Thu, Feb 5, 2026 at 4:36 PM Florian Weimer <fweimer@redhat.com> wrote:
>> > >>>
>> > >>> * Tomasz Kamiński:
>> > >>>
>> > >>> > +#  if __ASSERT_VARIADIC
>> > >>> > +#    define assert(...)                                                      \
>> > >>> > +     ((__VA_ARGS__)                                                  \
>> > >>> > +      ? (void)(1 ? 1 : bool(__VA_ARGS__))                            \
>> > >>> > +      : __assert_fail (#__VA_ARGS__, __ASSERT_FILE, __ASSERT_LINE,   \
>> > >>> > +                       __ASSERT_FUNCTION))
>> > >>>
>> > >>> Doesn't this evaluate __VA_ARGS__ multiple times?
>> > >>
>> > >> I got the same question initially when I saw this solution, but
>> > >> the second bool(__VA_ARGS) is in the false branch of the ternary:
>> > >> 1 ? 1 : bool(__VA_ARGS__)
>> > >> So it is never evaluated.
>> > >
>> > > Right, it's never evaluated, it's only there to enforce that
>> > > __VA_ARGS__ expands to a single expression, because bool(x,y) is
>> > > ill-formed.
>> >
>> > Ahh, we used sizeof for that before.   And static_cast<bool> (…).
>>
>> No and no. See the email that I just sent.
>>
>> sieof imposes other restrictions, because certain C++ constructs are
>> ill-formed if they occur in a sizeof expression. Specifically co_await
>> and co_return. Now there's no reason to every use those in the
>> expression used with assert, but there's also no reason to use sizeof
>> when we can use the less restricted bool(__VA_ARGS__) construct
>> instead.

Oh, and sizeof also has problems for lambda expressions before C++20,
so this doesn't work:

a.cc:5:19: error: lambda-expression in unevaluated context only
available with ‘-std=c++20’ or ‘-std=gnu++20’
   5 |   assert( []{ return true; }() );
     |                   ^


>>
>> And static_cast<bool>(...) will convert scoped enums, which we don't want.
>
> Enums are made ill-formed by (__VA_ARGS__) ?, so I think static_cast<bool>
> would be fine.

Oh I thought Florian meant replacing the first (__VA_ARGS__) with
static_cast<bool>(__VA_ARGS__).

Yes, I agree that the unevaluated bool(__VA_ARGS__) could use static_cast.

>>
>>
>> enum class E { e1 };
>> assert(e1); // this should not compile
>>
>>
>> > Would it make sense to keep that?  Current GCC seems to warn for
>> > bool (…), too, and Clang warns for neither, so the new approach
>> > is probably okay as well.
>> >
>> > Thanks,
>> > Florian
>> >
>>



More information about the Libc-alpha mailing list