Paul Eggert asked: > > #include <assert.h> > > #undef/**/assert > > + /* Solaris 11.4 <assert.h> defines static_assert as a macro with 2 > > arguments. > > + We need it also to be invocable with a single argument. */ > > + #if defined __sun && (__STDC_VERSION__ - 0 >= 201112L) && !defined > > __cplusplus > > + #undef static_assert > > + #define static_assert _Static_assert > > + #endif > > #endif]) > > Will this approach work if code does something like the following? I > worry that the later <assert.h> includes would collide with config.h's > definition of static_assert. > > #include <config.h> > > #define NDEBUG 1 > #include <assert.h> > > #define NDEBUG 0 > #include <assert.h> > > static_assert (true);
It will work. The reason is that <assert.h> looks like this: #ifndef _ASSERT_H #define _ASSERT_H /* Part 1: definitions that don't depend on NDEBUG */ #endif /* Part 2: definitions that depend on NDEBUG */ and the definition of 'static_assert', on Solaris 11.4, happens to be in part 1. > Come to think of it, the latest C23 draft is a little squirrelly here, > as its section 7.2 says that <assert.h> defines a static_assert macro. > This must be a typo because it never goes no to say anything about what > the macro does, and static_assert is a keyword in C23. I agree. Still, 'static_assert' is _allowed_ to be a macro, by ยง 6.10.9.(2). > Also, while we're on the topic, why does the latest C23 draft require > that when NDEBUG is defined, the assert macro is defined via "#define > assert(...) ((void)0)" rather than as "#define assert(ignore) > ((void)0)"? What's the point of requiring the ellipsis? I would guess that it's for compatibility for C++. ISO C++ 17 does not require anything about the argument when NDEBUG is defined. Thus, a program can contain #undef NDEBUG assert (new HashMap<A,B>(3).count == 0); and the compiler should effectively ignore this. But when the types HashMap, A, and B are not defined, the only way to ignore this line is to allow multiple arguments to 'assert' at the preprocessor level. (Because of the comma.) Most <assert.h> implementations get this wrong. Effectively requiring the programmer to insert extra parentheses: #undef NDEBUG assert ((new HashMap<A,B>(3).count == 0)); instead. Bruno
