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

Jonathan Wakely jwakely@redhat.com
Thu Feb 5 15:57:11 GMT 2026


On Thu, 5 Feb 2026 at 15:48, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> 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.

Maybe it needs a comment explaining the logic, and saying "Be careful
when touching this, every piece of it is load-bearing!" ;-)

The key pieces are that this relies on the "contextually converted to
bool" rule <https://wg21.link/conv.general#4>

(__VA_ARGS__) ? expr : __assert_fail(...);

This is a "weaker" form of conversion than casting to bool, and so
prevents scoped enum types from being asserted on (they aren't
convertible to integers, so they shouldn't be implicitly converted to
'true;' or 'false' in assertions).

And as explained above, the (void)(1 ? 1 : bool(__VA_ARGS__)) part has
no side effects but ensures that assert(x, y) is ill-formed, at least
when NDEBUG is not defined.



More information about the Libc-alpha mailing list