Some of my C macros, which need to expand to integer constant expressions, have compile time assertions in them based on:
#define stc_assert_expr(CexprB) sizeof(struct{int _:(CexprB)?1:-1;})
which could be alternatively spelled as
#include <assert.h>
#define stc_assert_expr(CexprB) sizeof(struct{static_assert(CexprB,#CexprB);})
//^not sure if this is legal C but it compiles with gcc and clang
//(I'm using the bitfield version anyway, which is definitely legal C)
Dumbified example usage:
#include <assert.h>
#define stc_assert_expr(CexprB) sizeof(struct{int _:(CexprB)?1:-1;})
int main(int argc, char**argv)
{
#define minus1(X) (0*stc_assert_expr((X)>0)+(X)-1) \
/*an integer constant expression with an assertionin it*/
char ar[minus1(3)];
switch(argc){
case minus1(2): ;
}
}
Suppose I wanted to make these macros usable in C++ also.
The above example doesn't work because C++ won't accept struct definitions inside sizeof
. Is there a C++ construct I can replace my stc_assert_expr(CexprB)
with that would keep the static_assert semantics?
You can use an array expression instead of a struct definition - negative array sizes are illegal in both languages: