
Originally Posted by
MartinR
The usage is as I mention - the programmer will always use the macro with constants known at compile time. Now the question is if we can verify them inside that #define ?
Usage - like
Code:
if ( IS_BIT_SET(255,8) ) {
// do something
}
Really limits your options as to what is syntactically valid inside your macro.
Things which can exist as statements have more scope.
Code:
#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1]
#define TOGGLE_BIT(x,y) do { \
STATIC_ASSERT((y<32),out_of_bound); \
(x) ^= (1 << (y)); \
} while ( 0 )
int main ( ) {
int x = 0;
TOGGLE_BIT(x,44);
}
$ gcc foo.c
foo.c: In function ‘main’:
foo.c:1:46: error: size of array ‘static_assertion_out_of_bound’ is negative
#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1]
^
foo.c:4:3: note: in expansion of macro ‘STATIC_ASSERT’
STATIC_ASSERT((y<32),out_of_bound); \
^
foo.c:10:3: note: in expansion of macro ‘TOGGLE_BIT’
TOGGLE_BIT(x,44);
^
foo.c:5:13: warning: left shift count >= width of type [-Wshift-count-overflow]
(x) ^= (1 << (y)); \
^
foo.c:10:3: note: in expansion of macro ‘TOGGLE_BIT’
TOGGLE_BIT(x,44);
^
But note that gcc already knows how to warn you about these things if the shift is known at compile time.