Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

237
Vistas
Comportamiento diferente de la macro C para diferentes casos

Este es el código,

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

El primer uso de la macro BUILD_BUG_ON(condición) arroja un error de compilación si el tamaño de la estructura no es igual a 8, ya que la condición se evaluará como verdadera. pero el segundo uso de la macro no arroja un error de compilación incluso si estoy proporcionando una condición verdadera. No soy capaz de entender este comportamiento. ¿Alguien puede explicar?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

La macro BUILD_BUG_ON está diseñada para implementar una aserción en tiempo de compilación.

Dado un argumento que se puede evaluar en tiempo de compilación, provoca un error en tiempo de compilación si el argumento es distinto de cero (verdadero) y no hace nada si el argumento es distinto de cero (falso).

No funciona para un argumento que se evalúa en tiempo de ejecución.

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

El !! son dos operadores lógicos "no"; tienen el efecto de normalizar un valor de 0 a 0 y cualquier valor distinto de cero a 1 .

Si la condición resultante es 1 (verdadera), entonces el valor de 1 - 2*!!(condition) es -1 . Si la condición es 0 (falsa), el valor es 1 .

Una matriz no puede tener un tamaño negativo (o cero). Algunos compiladores pueden admitir matrices de longitud cero como una extensión; esta macro asegura que incluso dicho compilador diagnostique un error. Si el tamaño es una expresión constante, una matriz con un tamaño negativo es una infracción de restricción y requiere un diagnóstico en tiempo de compilación.

Si la expresión es falsa, entonces no hay error; la macro se expande a una expresión que no hace nada. Si la expresión es verdadera y es una expresión constante , la expansión de la macro intenta definir una matriz de tamaño negativo, lo que genera un error en tiempo de compilación.

Si la expresión no es constante, la macro no funciona. C (C99 y posterior) permite matrices de longitud variable (VLA). No se permiten VLA de longitud cero o negativa, pero la definición de dicho VLA no se puede detectar en general en el momento de la compilación. Es un comportamiento indefinido y, en este caso, es probable que no haga nada. (Solo para complicar las cosas, los VLA no están permitidos en el alcance del archivo).

La macro debería, idealmente, ir acompañada de documentación que explique cómo usarla. Esa documentación debe explicar que el argumento debe ser una expresión en tiempo de compilación.

En pocas palabras: solo debe usar esta macro con un argumento de expresión constante. (Para probar una expresión en tiempo de ejecución, puede usar assert() .) Si usa una expresión no constante con un valor cero, el comportamiento no está definido; el resultado más probable es que la "afirmación" prevista no se active y no se detecte el error.

over 4 years ago · Santiago Trujillo Denunciar

0

Cambio

 BUILD_BUG_ON(cond);

para

 BUILD_BUG_ON(1);

para obtener el comportamiento esperado.

Cuando el valor de cond está disponible solo en tiempo de ejecución, se genera un código que calcula el sizeof requerido (y se descarta su resultado) en compilaciones no optimizadas, o se ignora por completo la expresión completa en compilaciones optimizadas.

over 4 years ago · Santiago Trujillo Denunciar

0

Creo que tu método es completamente antinatural.
Es un código incorrecto, incluso si funcionara.
Puede probar enfoques más naturales para manejar los errores.

afirmar

La afirmación de assert prueba una condición en tiempo de ejecución y muestra un mensaje de error si la prueba falla.

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

afirmación_estática

En los compiladores de quejas de C11, static_assert(condition, "Error message") hace lo que desea para las expresiones constantes:

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

#si y #error

También se podrían usar las directivas del compilador #if y #error , pero no le aconsejo en este caso, ya que #if no entiende sizeof .

La sintaxis sería:

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

Algunos de estos tres métodos tendrían que satisfacer sus necesidades.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda