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

Re: [perl #123327] [PATCH] define and use STATIC_ASSERT for compile-timeinvariants

Thread Previous | Thread Next
From:
Lukas Mai
Date:
November 29, 2014 14:37
Subject:
Re: [perl #123327] [PATCH] define and use STATIC_ASSERT for compile-timeinvariants
Message ID:
5479DA1F.2060102@gmail.com
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".

> +#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.

> 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.


-- 
Lukas Mai <plokinom@gmail.com>

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