[PATCH] assert: Support assert as variadic macro for C++26 [PR27276]
Tomasz Kaminski
tkaminsk@redhat.com
Wed Feb 18 08:09:38 GMT 2026
On Tue, Feb 17, 2026 at 8:03 PM Paul Eggert <eggert@cs.ucla.edu> wrote:
> 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.
>
Let me expand this a bit, to run that test I need to modify the makefile to
have:
CFLAGS-test-assert-c++-variadic.o = -std=c++26
LDLIBS-test-assert-c++-variadic = -lstdc++
But that means, that check will fail when tested on a platform that uses GCC
that is not new enough to support -std=c++26. We currently use the ifeq
($(have-cxx-thread_local),yes):
```
ifeq ($(have-cxx-thread_local),yes)
CFLAGS-tst-assert-c++.o = -std=c++11
LDLIBS-tst-assert-c++ = -lstdc++
CFLAGS-tst-assert-g++.o = -std=gnu++11
LDLIBS-tst-assert-g++ = -lstdc++
else
tests-unsupported += \
tst-assert-c++ \
tst-assert-g++ \
```
to guard such uses of -std=c++11, but I haven't found an example of how to
do that for other language options, i.e. make the test
> > + : 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.
The intent at this point is to apply the scoped enumeration fix to C++26
only, and after seeing the amount of breakage backport it to the previous
standard.
(It is accepts-invalid case, and could be widely used).
Regards,
Tomasz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20260218/6394fd9c/attachment-0001.htm>
More information about the Libc-alpha
mailing list