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

Jonathan Wakely jwakely@redhat.com
Tue Feb 17 10:34:14 GMT 2026


On Mon, 16 Feb 2026 at 21:59, Paul Eggert <eggert@cs.ucla.edu> wrote:
>
> On 2026-02-09 03:27, Tomasz Kamiński wrote:
>
> > Mainly for testing purposes we allow enabling/disabling variadic assert
> > regardless of version of C or C++, by defining __ASSERT_VARIADIC to
> > 1/0 respectively before inclusion of <assert>
>
> I don't see the need for this extra complexity in this patch. People who
> want to do that sort of testing can do it in other ways. If there is a
> need, this part of the patch should be separated out into a different patch.
>
> > +   Similary C++26 makes assert a variadic macro and allows expressions
> > +   containing template argument lists, lambda captures, and many others
> > +   that include commas, without requiring extra parentheses.
>
> "Similarly" is misspelled. Plus, this comment talks about the wrong
> things. The key question (which the containing comment already answers
> for C) is which versions of the language standard and of GCC support the
> proposed implementation of variadic assert for C++. That's what the
> comment should talk about, not about which features of C++ can use the
> proposed patch. Or maybe it's simpler to just remove this comment
> entirely, if all versions of the standard and GCC support it.
>
> > +#  if (__GLIBC_USE (ISOC23)                                          \
> > +       && (defined __GNUC__                                          \
> > +        ? __GNUC_PREREQ (3, 0)                                       \
> > +        : defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)   \
> > +       || (defined __cplusplus && __cplusplus >= 202302L))
>
> Parenthesis are missing around the first disjunct.
>
> More importantly, that "__cplusplus >= 202302L" looks wrong. This is a
> C++26 feature, right? Shouldn't it be "__cplusplus > 202302L"? Using
> ">=" would cause g++ to not diagnose some invalid C++23 programs, even
> in pedantic mode.
>
> > +#   define __ASSERT_VARIADIC 1
> > +#  else
> > +#    define __ASSERT_VARIADIC 0
> > +#  endif
> >   #endif
> >
> >   /* void assert (int expression);
> > @@ -108,7 +112,7 @@ extern void __assert (const char *__assertion, const char *__file, int __line)
> >        __THROW __attribute__ ((__noreturn__)) __COLD;
> >   __cplusplus >= 202302L
> >
> > -# if __ASSERT_VARIADIC
> > +# if __ASSERT_VARIADIC && !defined __cplusplus
> >   /* This function is not defined and is not called outside of an
> >      unevaluated sizeof, but serves to verify that the argument to
> >      assert is a single expression.  */
> > @@ -131,11 +135,19 @@ __END_DECLS
> >   #   define __ASSERT_FILE __FILE__
> >   #   define __ASSERT_LINE __LINE__
> >   #  endif
> > -#  define assert(expr)                                                       \
> > +#  if __ASSERT_VARIADIC
> > +#    define assert(...)                                                      \
> > +     ((__VA_ARGS__)                                                  \
> > +      ? (void)(1 ? 1 : bool(__VA_ARGS__))                            \
> > +      : __assert_fail (#__VA_ARGS__, __ASSERT_FILE, __ASSERT_LINE,   \
> > +                       __ASSERT_FUNCTION))
>
> The proposed spacing near parens doesn't conform to the usual glibc style.
>
> Why use '(void)(...) rather than 'void (...)' as the other arm does?
>
> More importantly, can't we simplify things by avoiding one repetition of
> __VA_ARGS__ and doing something like the following instead?

No. Every part of the macro is load-bearing.

We do not want to do an explicit conversion to bool, because that
would allow asserting on things which are not supposed to be
interpreted as true or false.

If you want to assert the integral value of a scoped enum, then you
must do the conversion yourself:

assert( (bool)Enum::E );

The C++ standard requires assert(Enum::E) to be ill-formed.

>
>   #define assert(...) \
>     (bool (__VA_ARGS__) \
>      ? void (0) \
>      : __assert_fail (#__VA_ARGS__, __ASSERT_FILE, __ASSERT_LINE, \
>                       __ASSERT_FUNCTION))

This would cause a test failure for the new tests added by the patch.



More information about the Libc-alpha mailing list