bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: assert-h: Make static_assert work on Solaris 11.4


From: Bruno Haible
Subject: Re: assert-h: Make static_assert work on Solaris 11.4
Date: Tue, 25 Oct 2022 22:05:47 +0200

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






reply via email to

[Prev in Thread] Current Thread [Next in Thread]