develooper Front page | perl.perl5.porters | Postings from January 2015

Re: [perl #123327] [PATCH] define and use STATIC_ASSERT forcompile-time invariants

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
January 21, 2015 13:04
Subject:
Re: [perl #123327] [PATCH] define and use STATIC_ASSERT forcompile-time invariants
Message ID:
20150121130400.GA29939@iabyn.com
On Sat, Nov 29, 2014 at 07:05:25AM -0800, Father Chrysostomos via RT wrote:
> 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.

I notice that these new macros are undocumented :-(

-- 
Nothing ventured, nothing lost.

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