ImpalerCore
4/20/2011 1:43:00 PM
On Apr 19, 11:13 am, Francois Grieu <fgr...@gmail.com> wrote:
> Under C89/90/99, there is no static assert allowing to check a
> constant expression at compile time. I often use
>
> #define ASSERT_S(condition) extern char assert_failure[(condition)?1:-1]
>
> e.g. in
>
> ASSERT_S(sizeof(foo)>=sizeof(bar));
> memcpy(foo,bar,sizeof(bar));
>
> But on some platforms there is a spurious warning or link time error
> (which I can't remember, and that would be OT). On these platforms
> I end up using
>
> #define ASSERT_S(condition) struct{char assert_s[(condition)?1:-1];}
>
> but it causes other issues on some other platforms. I recall things
> depend on if ASSERT_S is used in global or function scope.
>
> There is
>
> #define ASSERT_S(condition) enum{ASSERT_Sy(__LINE__)=sizeof(char[(condition)?1:-1])}
> #define ASSERT_Sy(j) ASSERT_Sz(j)
> #define ASSERT_Sz(j) assert_s##j
>
> and it often works fine, but using that ASSERT_S twice on same-numbered
> lines (e.g twice on a line, or different but same-numbered lines in different
> header files used in the same compilation unit) will fail.
>
> Except when __COUNTER__ is available, workarounds get hairy:
> #define ASSERT_S(condition) enum{ASSERT_Sy(__LINE__,HDR_NAME)=sizeof(char[(condition)?1:-1])}
> #define ASSERT_Sy(j,n) ASSERT_Sz(j,n)
> #define ASSERT_Sz(j,n) assert_s##j##n
>
> with the convention that any header file should be structured as
> #include "other_header.h"
> #define HDR_NAME myuniquename
> /* here ASSERT_S is usable */
> #undef HDR_NAME
>
> Can this be improved upon, towards the grail of working almost everywhere
> without special-casing for this or that environment?
Not sure if you would consider this an improvement, but my version
parameterizes the name.
\code snippet
#define C_STATIC_ASSERT(name, expr) extern char (name)[(expr) ? 1 :
-1]
C_STATIC_ASSERT( CHAR_BIT_is_8_bits, CHAR_BIT == 8 );
C_STATIC_ASSERT( sizeof_int_at_least_32_bits, sizeof(int) >= 4 );
\endcode
That way, when you get a failure, you get the label in the error
output like this:
C_STATIC_ASSERT_example.c:4: error: size of array
`sizeof_int_at_least_32_bits' is negative.
You could try giving each static assertion a unique name and see if
it's more portable in your environments.
Best regards,
John D.