develooper Front page | perl.perl5.porters | Postings from November 2014

[perl #123327] [PATCH] define and use STATIC_ASSERT for compile-time invariants

Thread Previous | Thread Next
From:
Father Chrysostomos via RT
Date:
November 29, 2014 15:05
Subject:
[perl #123327] [PATCH] define and use STATIC_ASSERT for compile-time invariants
Message ID:
rt-4.0.18-18144-1417273524-1156.123327-15-0@perl.org
On Sat Nov 29 06:37:39 2014, plokinom@gmail.com wrote:
> Am 29.11.2014 um 15:17 schrieb Father Chrysostomos via RT:
> >
> > Two questions, because I’m not a C expert:
> >
> > +#if defined(static_assert) || (defined(__cplusplus) && __cplusplus
> > >= 201103L)
> > +/* static_assert is a macro defined in <assert.h> in C11 or a
> > compiler
> > +   builtin in C++11.
> > +*/
> > +#  define STATIC_ASSERT_GLOBAL(COND) static_assert(COND, #COND)
> >
> > What does the # do in #COND?
> 
> It stringifies a macro parameter (i.e. turns a token sequence into a
> string literal). static_assert can be used like this:
> 
> static_assert((FOO & 7) == 0, "lower bits of FOO must be zero");
> 
> and the compiler will output something like
> 
> foo.c, line 123: static assertion failed: lower bits of FOO must be
> zero
> 
> With STATIC_ASSERT_GLOBAL((FOO & 7) == 0); it would simply say
> something
> like "static assertion failed: (FOO & 7) == 0".

I see.

> > +#else
> > +/* We use a bit-field instead of an array because gcc accepts
> > +   'typedef char x[n]' where n is not a compile-time constant.
> > +   We want to enforce constantness.
> > +*/
> > +#  define STATIC_ASSERT_2(COND, SUFFIX) \
> > +    typedef struct { \
> > +        unsigned int _static_assertion_failed_##SUFFIX : (COND) ? 1
> > : -1; \
> > +    } _static_assertion_failed_##SUFFIX PERL_UNUSED_DECL
> > +#  define STATIC_ASSERT_1(COND, SUFFIX) STATIC_ASSERT_2(COND,
> > SUFFIX)
> > +#  define STATIC_ASSERT_GLOBAL(COND)    STATIC_ASSERT_1(COND,
> > __LINE__)
> >
> > Why the layer of indirection?  Why not just
> >
> > +#  define STATIC_ASSERT_GLOBAL(COND)    STATIC_ASSERT_2(COND,
> > __LINE__)
> >
> > ?
> 
> I tried that and it generated the name
> _static_assertion_failed___LINE__
> (instead of _static_assertion_failed_123). I don't know the exact
> rules,
> but I know I can trigger macro expansion in macro parameters by adding
> more indirection.

Makes sense.

Thank you.  I have applied your patch as 6d59e610a.

> > Also, would it be a good idea to do ASSUME() in STATIC_ASSERT_STMT,
> > for the sake of non-debugging builds?
> 
> I don't understand this.
> 1) Anything that can be STATIC_ASSERTed is stuff the compiler already
> knows.
> 2) STATIC_ASSERT_* are defined regardless of whether DEBUGGING is on
> or not.

Never mind that, then. :-)

-- 

Father Chrysostomos


---
via perlbug:  queue: perl5 status: open
https://rt.perl.org/Ticket/Display.html?id=123327

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About