F
Francois Grieu
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?
TIA,
Francois Grieu
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?
TIA,
Francois Grieu