Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

245
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda