5 ms·
That code seems needlessly arcane. You can get the same results without resorting to anonymous bitfields: #define BUILD_BUG_ON_ZERO(e) (sizeof(char[(e) ? -1
by Mindless2112 10y ago
That code seems needlessly arcane. You can get the same results without resorting to anonymous bitfields:
#define BUILD_BUG_ON_ZERO(e) (sizeof(char[(e) ? -1 : 0]))
which, when it fails, results in
error: size of unnamed array is negative
which is no worse than the provided code which results in
error: negative width in bit-field '<anonymous>'
It's worth noting that declaring an array with 0 elements is not allowed in C99. However, using a struct with no named members has undefined behavior in C99 [1].
[1] http://stackoverflow.com/a/12918937/959866 http://stackoverflow.com/a/12918937/959866
Edit: You can get around having 0 elements by using
#define BUILD_BUG_ON_ZERO(e) (sizeof(char[(e) ? -1 : 1]) - 1)
but you're starting to lose clarity again.
- peterdn 10y agoIn some compilers due to C99 variable length arrays [1], your macro compiles happily if passed a value that is not a compile-time constant. For example, this compiles but segfaults at runtime (GCC 4.9.2): int main(int argc, char * argv[]) { return (sizeof(char[(argc) ? -1 : 1]) - 1); } [1] https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
- Mindless2112 10y agoAh, good point. One more reason for me to hate VLAs. ;) The negative-length array trick is used in the Linux kernel source code [1]. I expect it's compiled with -Wvla though. [1] https://github.com/torvalds/linux/blob/v4.5/arch/x86/boot/boot.h#L32 https://github.com/torvalds/linux/blob/v4.5/arch/x86/boot/bo...
- Sacho 10y agoLooks exactly like the macro Jan Beulich replaced with the one discussed in OP: https://github.com/torvalds/linux/commit/8c87df457cb58fe75b9b893007917cf8095660a0 https://github.com/torvalds/linux/commit/8c87df457cb58fe75b9...
- pjmlp 10y agoThey are so good that they became optional in C11[0] and thankfully were not adopted by ANSI C++. [0] - ISO 9899:2011 Programming Languages - C 6.7.6.2 4
- thomasahle 10y ago-#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) +#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); })) The commit that introduced the notation, actually used something similar to your second approach: https://github.com/torvalds/linux/commit/8c87df457cb58fe75b9b893007917cf8095660a0#diff-23e29fa8c20b4af09028e20e4131f1f5L687 https://github.com/torvalds/linux/commit/8c87df457cb58fe75b9...