svn commit: r358392 - head/share/man/man9

Warner Losh imp at bsdimp.com
Fri Feb 28 05:46:55 UTC 2020


On Thu, Feb 27, 2020, 9:17 PM Mark Millard <marklmi at yahoo.com> wrote:

> [Ignoring llvm-project and libstdc++, I only find
> about 24 other instances of "static_assert".]
>
> On 2020-Feb-27, at 19:03, Mark Millard <marklmi at yahoo.com> wrote
>
> > On 2020-Feb-27, at 16:37, John Baldwin <jhb at FreeBSD.org> wrote:
> >
> >> On 2/27/20 2:45 PM, Mark Millard wrote:
> >>> John Baldwin jhb at FreeBSD.org wrote on
> >>> Thu Feb 27 16:55:01 UTC 2020:
> >>>
> >>>> On 2/27/20 7:30 AM, Warner Losh wrote:
> >>>>> Author: imp
> >>>>> Date: Thu Feb 27 15:30:13 2020
> >>>>> New Revision: 358392
> >>>>> URL: https://svnweb.freebsd.org/changeset/base/358392
> >>>>>
> >>>>> Log:
> >>>>> _Static_assert is to be preferred to CTASSERT.
> >>>>>
> >>>>> Document the existing prefernce that _Static_assert be used in
> preference to the
> >>>>> old CTASSERT we used to use for compile time assertions.
> >>>>
> >>>> Actually, I think what we want to use is static_assert().  The
> intention in
> >>>> userland C is that _Static_assert() is an internal keyword and
> <assert.h>
> >>>> adds static_assert() as an alias, similar to <stdalign.h> defining
> alignas,
> >>>> etc.  I think what we should do for the kernel is have <sys/systm.h>
> define
> >>>> map static_assert to _Static_assert and replace existing
> _Static_assert
> >>>> usage with the proper spelling.
> >>>>
> >>>
> >>> Be warned static_assert is a C++ keyword as of C++11.
> >>>
> >>> c++11 added: static_assert(bool_constexpr,message)
> >>> c++17 added: static_assert(bool_constexpr)
> >>>
> >>> C11 added _Static_assert(expression,message)
> >>> C2x gets  _Static_assert(expression)
> >>>
> >>> C11 added "#define static_assert _Static_assert" to <assert.h>
> >>>
> >>> It makes for a bit of a mess in code to be allowed
> >>> to be processed by both C and C++.
> >>>
> >>> The wording may need to specify enough to tell what to
> >>> do for such code and the headers may need logic to
> >>> cause that context to exist across both languages
> >>> when the header is allowed for both.
> >>
> >> The intent of the C11 changes is to permit equivalent use of
> static_assert()
> >> in both languages.  The #define in <assert.h> is guarded to not kick in
> for
> >> C++.
> >
> > Ahh. I had vague memories of past oddities in the area
> > that I was involved in. So I looked and found (in head
> > -r3578132 source) :
> >
> > # more /usr/src/sys/sys/cdefs.h
> > . . .
> > #if !__has_extension(c_static_assert)
> > #if (defined(__cplusplus) && __cplusplus >= 201103L) || \
> >    __has_extension(cxx_static_assert)
> > #define _Static_assert(x, y)    static_assert(x, y)
> > #elif __GNUC_PREREQ__(4,6) && !defined(__cplusplus)
> > /* Nothing, gcc 4.6 and higher has _Static_assert built-in */
> > #elif defined(__COUNTER__)
> > #define _Static_assert(x, y)    __Static_assert(x, __COUNTER__)
> > #define __Static_assert(x, y)   ___Static_assert(x, y)
> > #define ___Static_assert(x, y)  typedef char __assert_ ## y[(x) ? 1 :
> -1] \
> >                                __unused
> > #else
> > #define _Static_assert(x, y)    struct __hack
> > #endif
> > #endif
> > . . .
> >
> > # more /usr/include/assert.h
> > . . .
> > /*
> > * Static assertions.  In principle we could define static_assert for
> > * C++ older than C++11, but this breaks if _Static_assert is
> > * implemented as a macro.
> > *
> > * C++ template parameters may contain commas, even if not enclosed in
> > * parentheses, causing the _Static_assert macro to be invoked with more
> > * than two parameters.
> > */
> > #if __ISO_C_VISIBLE >= 2011 && !defined(__cplusplus)
> > #define static_assert   _Static_assert
> > #endif
> > . . .
> >
> > So one can define a _Static_assert macro, sometimes in terms of
> > static_assert, and the other sometimes defines a static_assert
> > macro in terms of _Static_assert.
> >
> > Messy, but possibly localized.
> >
> > That prompted a more general grep:
> >
> > # grep -r "define[     _]*[Ss]tatic_assert" /usr/src/* | more
> > /usr/src/contrib/llvm-project/libcxx/include/__config:# define
> static_assert(...) _Static_assert(__VA_ARGS__)
> > /usr/src/contrib/llvm-project/libunwind/src/config.h:  #define
> static_assert(__b, __m) \
> > /usr/src/include/assert.h: * Static assertions.  In principle we could
> define static_assert for
> > /usr/src/include/assert.h:#define       static_assert   _Static_assert
> > /usr/src/sys/sys/cdefs.h:#define        _Static_assert(x, y)
> static_assert(x, y)
> > /usr/src/sys/sys/cdefs.h:#define        _Static_assert(x, y)
> __Static_assert(x, __COUNTER__)
> > /usr/src/sys/sys/cdefs.h:#define        __Static_assert(x, y)
>  ___Static_assert(x, y)
> > /usr/src/sys/sys/cdefs.h:#define        ___Static_assert(x, y)  typedef
> char __assert_ ## y[(x) ? 1 : -1] \
> > /usr/src/sys/sys/cdefs.h:#define        _Static_assert(x, y)    struct
> __hack
> > /usr/src/usr.bin/dtc/util.hh:#define static_assert(x, y) ((void)0)
> >
> > So not much else.
>
> Just an FYI: Looks like static_assert is little used (outside
> llvm-project and libstdc++):
>
> # grep -r "\<static_assert\>" /usr/src/* | grep -v llvm-project | grep -v
> "libstdc\+\+" | more
> /usr/src/contrib/googletest/googlemock/include/gmock/gmock-matchers.h:
>   static_assert(
> /usr/src/contrib/googletest/googlemock/include/gmock/gmock-matchers.h:
> static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
> /usr/src/contrib/googletest/googlemock/docs/DesignDoc.md:Google Test (the
> name is chosen to match `static_assert` in C++0x).
> /usr/src/contrib/googletest/googletest/include/gtest/internal/gtest-port.h:#
> define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
> /usr/src/contrib/googletest/googletest/include/gtest/internal/gtest-port.h://
> (In C++11, we simply use static_assert instead of the following)
> /usr/src/contrib/bsnmp/snmpd/trans_inet.c:static_assert(offsetof(struct
> port_sock, input) == 0,
> /usr/src/contrib/bsnmp/snmpd/trans_inet.c:static_assert(offsetof(struct
> inet_port, tport) == 0,
> /usr/src/contrib/libcxxrt/guard.cc:static_assert(sizeof(guard_t) ==
> sizeof(uint64_t), "");
> /usr/src/contrib/ofed/libibumad/umad.c:static_assert(sizeof(struct
> ib_user_mad_reg_req) == IOCPARM_LEN(IB_USER_MAD_REGISTER_AGENT),
> /usr/src/contrib/ofed/libibumad/umad.c:static_assert(sizeof(struct
> ib_user_mad_reg_req2) == IOCPARM_LEN(IB_USER_MAD_REGISTER_AGENT2),
> /usr/src/include/assert.h: * Static assertions.  In principle we could
> define static_assert for
> /usr/src/include/assert.h:#define       static_assert   _Static_assert
> /usr/src/sys/sys/cdefs.h:#define        _Static_assert(x, y)
> static_assert(x, y)
> /usr/src/sys/contrib/zstd/contrib/pzstd/utils/FileSystem.h:
> static_assert(false, "No POSIX stat() support.");
> /usr/src/sys/contrib/zstd/contrib/pzstd/utils/FileSystem.h:
> static_assert(false, "NO POSIX stat() support.");
> /usr/src/usr.bin/dtc/HACKING:The code also makes use of `static_assert()`
> to track compile-time invariants.
> /usr/src/usr.bin/dtc/util.hh:#ifndef static_assert
> /usr/src/usr.bin/dtc/util.hh:#define static_assert(x, y) ((void)0)
> /usr/src/usr.bin/dtc/util.hh:   static_assert(sizeof(T) > 1,
> /usr/src/usr.sbin/bhyve/task_switch.c:static_assert(sizeof(struct tss32)
> == 104, "compile-time assertion failed");
> /usr/src/usr.sbin/bhyve/pci_emul.h:static_assert(sizeof(struct msicap) ==
> 14, "compile-time assertion failed");
> /usr/src/usr.sbin/bhyve/pci_emul.h:static_assert(sizeof(struct msixcap) ==
> 12, "compile-time assertion failed");
> /usr/src/usr.sbin/bhyve/pci_emul.h:static_assert(sizeof(struct pciecap) ==
> 60, "compile-time assertion failed");
> /usr/src/usr.sbin/syslogd/syslogd.c:
> static_assert(sizeof(f->f_prevline) == sizeof(saved),
>
> _Static_assert looks to be far more common. (Too long
> to list here.)
>

Right.. originally I was going to document static_asset(), but then people
on irc said the other was far more common. A quick grep confirmed it. So it
met my test of documenting an overwhelming practice.

Whether we should change or not is a separate question.

Warner

===
> Mark Millard
> marklmi at yahoo.com
> ( dsl-only.net went
> away in early 2018-Mar)
>
>


More information about the svn-src-head mailing list