Chuck(G)
25k Member
Thought I'd submit a C chestnut for those who might not know about it. Suppose that I wanted to check the size of a struct in C (C++ has a workaround) at compile time without generating any code. The issue is that the C preprocessor doesn't know anything about the sizeof() operator and will always return 0. You could use an "assert" statement (assert.h), but that generates code and operates only at run-time. What you really want is to be alerted to a size miscalculation at compile time.
Here's a solution and example:
If the size agrees, the compiler will be silent, but if it disagrees, you'll get an error message like the following:
Here's another one, applicable to GCC only, as far as I know. Suppose you have a number of big-endian values and you want to convert them to little-endian ones. You could use explicit functions (AND, shift and OR) to do it, or you could use the builtin swapxx library functions. Normally, you'd have to do that with care, so that the swap function matched the width of the big-endian variable. Howeverr, you can use a single unified preprocessor macro to handle that:
Thus, if a big-endian variable is 8, 16, 32, or 64 bits, BEGET() will pick the appropriate function automatically.
Here's a solution and example:
Code:
#ifndef size_assert
#define size_assert( what, howmuch ) \
typedef char what##_size_wrong_[( !!(sizeof(what) == howmuch) )*2-1 ]
#endif
size_assert( CMS_END, CMS_END_SIZE);
Code:
cms.h:56:14: error: size of array ‘CMS_END_size_wrong_’ is negative
56 | size_assert( CMS_END, CMS_END_SIZE);
| ^~~~~~~
Here's another one, applicable to GCC only, as far as I know. Suppose you have a number of big-endian values and you want to convert them to little-endian ones. You could use explicit functions (AND, shift and OR) to do it, or you could use the builtin swapxx library functions. Normally, you'd have to do that with care, so that the swap function matched the width of the big-endian variable. Howeverr, you can use a single unified preprocessor macro to handle that:
Code:
// Macro to get value of a BE value--uses GCC builtins
#define BEGET(x) \
__builtin_choose_expr ( \
__builtin_types_compatible_p( typeof(x), uint16_t),\
__builtin_bswap16(x), \
__builtin_choose_expr ( \
__builtin_types_compatible_p( typeof(x), uint32_t),\
__builtin_bswap32(x), \
__builtin_choose_expr ( \
__builtin_types_compatible_p( typeof(x), uint64_t),\
__builtin_bswap64(x), \
x )))
Last edited: