[PATCH v3] assert: Support assert as variadic macro for C++26 [PR27276]
Tomasz Kaminski
tkaminsk@redhat.com
Tue Feb 17 10:00:53 GMT 2026
On Mon, Feb 16, 2026 at 11:04 PM 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.
>
I would really appreciate guidance on how I could test this in other ways,
in a robust manner. I was simply considering guarding the content
test-assert-c++-variadic.cc with appropriate __cplusplus value,
but this led to de-facto dead-test.
The problem I am facing is that the test would need to be compiled with
"-std=c++26", but that is not supported by all versions of GCC that glibc
targets. I have looked into how C23 is tested, to see how to conditionally
pass --std=c23 flag, but they seem to rely on defining ISOC23_SOURCES.
> > + 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.
>
It is supported in all versions of GCC that support C++26 standard, so I
will
simply remove 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.
>
The first disjunct is directly placed inside if, i.e. is enclosed by
outermost
parenthesis. Do you want me to add a second pair?
>
> 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.
>
I have double checked, and the feature was voted in C++26. I will fix the
above. Thank you!
>
> > +# 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?
>
I will double check if there is a difference (we already found subtle
differences
between the syntaxes), if not I will switch to the proposed syntax.
>
> More importantly, can't we simplify things by avoiding one repetition of
> __VA_ARGS__ and doing something like the following instead?
>
As I have mentioned in the commit message, and also glibc PR/27276 [2],
use of bool(__VA_ARGS__) is non-conforming according to C++ standard,
as it accepts expression of types that are explicitly convertible, but not
contextually convertible to bool. In particular this includes scoped
enumerations.
This is why I believe having a dedicated and functioning c++ variadic test
is
very valuable, and I am hesitant to remove __ASSERT_VARIADIC change,
if we do not have a good alternative.
Regards,
Tomasz
>
> #define assert(...) \
> (bool (__VA_ARGS__) \
> ? void (0) \
> : __assert_fail (#__VA_ARGS__, __ASSERT_FILE, __ASSERT_LINE, \
> __ASSERT_FUNCTION))
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20260217/23d3fb36/attachment-0001.htm>
More information about the Libc-alpha
mailing list