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

Paul Eggert eggert@cs.ucla.edu
Tue Feb 17 19:02:50 GMT 2026


On 2026-02-17 06:48, Tomasz Kamiński wrote:

> 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.

One possibility is that a test case that wants __ASSERT_VARIADIC can do 
"sed 's/\(define __ASSERT_VARIADIC\) [01]/\1 1/' .../assert.h >assert.h" 
and then compile the test with "gcc -I.". That's robust enough for a 
test. But see below.

> 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.

I'm a little lost here. It sounds like you're trying to test the C++26 
features of the new <assert.h> even on C++23 platforms. Why bother? Just 
test the platform that you have. If it's a "dead-test" that's OK; the 
feature isn't supported on that platform and need not be tested.

> +	    : defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))	\
> +       || (defined __cplusplus && __cplusplus > 202302L))
> +#   define __ASSERT_VARIADIC 1
> +#  else
> +#    define __ASSERT_VARIADIC 0
> +#  endif

Please indent consistently with the rest of the file: only one space 
used for each level after a "#". Here, the second "if" is indented too 
much, and the then- and else-parts are not evenly indented.

> +   validate that only a single expression is passed as an argument. */

Two spaces after period.

> +#  if __ASSERT_VARIADIC
> +#    define assert(...)							\
> +     ((__VA_ARGS__)							\
> +      ? void (1 ? 1 : bool (__VA_ARGS__))				\
> +      : __assert_fail (#__VA_ARGS__, __ASSERT_FILE, __ASSERT_LINE,	\
> +                       __ASSERT_FUNCTION))
> +#  else
> +#    define assert(expr)						\
>        (static_cast <bool> (expr)						\
>         ? void (0)							\
>         : __assert_fail (#expr, __ASSERT_FILE, __ASSERT_LINE,             \
>                          __ASSERT_FUNCTION))
> +#  endif

The then- and else- parts now use different techniques even though the 
first technique would work in the else-part, i.e., the else-part could 
be changed to this:

  #  define assert(expr)						\
      ((expr)							\
       ? void (1 ? 1 : bool (expr))				\
       : __assert_fail (#expr, __ASSERT_FILE, __ASSERT_LINE,     \
                        __ASSERT_FUNCTION))

To help explain this seemingly-unnecessary difference, I suggest adding 
a comment like the following to the then-part: "The first test of 
__VA_ARGS__ evaluates it without converting scoped enumeration values to 
bool, and the second test checks that it is a single expression without 
evaluating it." This would help lessen the confusion I had in my earlier 
review.

In addition, you might consider altering the else-part as shown above, 
and then moving the comment to be outside the #if.



More information about the Libc-alpha mailing list