Different C macro behavior for different cases

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;
}

The first use of the BUILD_BUG_ON macro (condition) throws a compilation error if sizeof struct is not 8, because the condition will evaluate to true. but the second use of the macro does not throw a compilation error, even if I provide a true condition. I can not understand this behavior. Can someone explain?

+4
source share
3 answers

The macro is BUILD_BUG_ONintended to implement compile-time statements.

Given an argument that can be evaluated at compile time, it causes compilation to fail 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 evaluates at runtime.

#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

!! - ""; 0 0, - 1.

1 (true), 1 - 2*!!(condition) -1. 0 (false), 1.

( ) . ; , . , , .

, ; , . , , .

, . C (C99 ) (VLA). VLA , VLA . undefined - , , . ( , VLA .)

, , , , . , .

: . ( , assert().) , undefined; , "" , .

+5

, . , .
.

assert

assert , .

 #include <assert.h>
 int main(void)
 {
     assert((sizeof(struct my_struct) % 8) != 0);
 }

static_assert

C11 static_assert(condition, "Error message") , :

static_assert((sizeof(struct my_struct) % 8) != 0, "Wrong struct");  

#if #error

#if #error, , sizeof #if.

:

#if some_condition // Put an integer constant expression readable by an #if.
#  error This is wrong.
#endif

.

+1

BUILD_BUG_ON(cond);

BUILD_BUG_ON(1);

.

cond , , sizeof, ( ) .

0

Source: https://habr.com/ru/post/1598526/


All Articles