This is the code,
#include<stdio.h>
#include<stdbool.h>
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
struct my_struct {
int a, b;
// char c;
};
int main() {
bool cond = 1;
BUILD_BUG_ON((sizeof(struct my_struct) % 8) != 0);
BUILD_BUG_ON(cond);
return 0;
}
first use of BUILD_BUG_ON(condition) macro is throwing compilation error if sizeof struct is not equal to 8 as the condition will evaluate to true. but second use of macro is not throwing compilation error even if i am providing true condition. I am not able to understand this behaviour. Can someone explain?
The BUILD_BUG_ON
macro is intended to implement a compile-time assertion.
Given an argument that can be evaluated at compile time, it causes a compile-time failure if the argument is non-zero (true), and does nothing if the argument is non-zero (false).
It does not work for an argument that is evaluated at run time.
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
The !!
is two logical "not" operators; they have the effect of normalizing a value of 0
to 0
, and any non-zero value to 1
.
If the resulting condition is 1
(true), then the value of 1 - 2*!!(condition)
is -1
. If the condition is 0
(false), the value is 1
.
An array may not have a negative (or zero) size. Some compilers might support zero-length arrays as an extension; this macro ensures that even such a compiler with diagnose an error. If the size is a constant expression, an array with a negative size is a constraint violation, requiring a compile-time diagnostic.
If the expression is false, then there's no error; the macro expands to an expression that does nothing. If the expression is true and is a constant expression, then the expansion of the macro attempts to define an array of negative size, resulting in a compile-time error.
If the expression is not constant, the macro doesn't work. C (C99 and later) permits variable-length arrays (VLAs). VLAs of zero or negative length are not permitted, but defining such a VLA cannot in general be detected at compile time. It is undefined behavior -- and in this case, it's likely to do nothing. (Just to complicate things VLAs are not permitted at file scope.)
The macro should, ideally, be accompanied by documentation that explains how to use it. That documentation should explain that the argument must be a compile-time expression.
Bottom line: You should only use this macro with a constant expression argument. (To test a run-time expression, you can use assert()
.) If you use a non-constant expression with a zero value, the behavior is undefined; the most likely result is that the intended "assertion" will not fire and the error will not be detected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With