Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

236
Views
Different behaviour of C macro 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;
}

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?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

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.

over 4 years ago · Santiago Trujillo Report

0

Change

BUILD_BUG_ON(cond);

to

BUILD_BUG_ON(1);

to obtain the expected behaviour.

When the cond value is available only in run time then a code that calculates the required sizeof is generated (and its result discarded) in unoptimized builds, or the whole expression is completely ignored in optimized builds.

over 4 years ago · Santiago Trujillo Report

0

I think your method is completely unnatural.
It's bad code, even if it would worked.
You can try more natural approaches to handle errors.

assert

The macro assert tests for a condition in runtime and shows an error message if the test fails.

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

static_assert

In C11 complaint compilers, static_assert(condition, "Error message") does what you want for constant expressions:

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

#if and #error

Also the #if and #error compiler directives could be used, but I don't advice you in this case, since sizeof is not understood by #if.

The syntax would be:

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

Some of these three methods would have to satisfy your needs.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!