¿Comparación de un campo de bits frente a un entero (negativo), comportamiento indefinido o errores de comstackción?

Aquí hay un pequeño progtwig. ¿Debería imprimirse 0 o 1, o tiene un comportamiento indefinido?

#include  struct S0 { unsigned f1 : 1; }; struct S0 s; int main (void) { int x = -3; int y = x >= (0, s.f1); printf ("%d\n", y); return 0; } 

Esto se toma de una prueba de CSmith reenviada, y este caso se discute más aquí .

En particular, GCC, KCC y CompCert producen 0, mientras que MSVC 2010, ICC 12.0.2 y los recientes resultados de Clang 1.

Interesante pregunta.

De acuerdo con el borrador de la norma C99 6.5.17.1, el tipo de (0, s.f1) es el mismo que el de s.f1 , que (según 6.7.2.1.9) es “un tipo entero sin signo que consta de 1 bit” . Este es un tipo aritmético por ser un tipo entero, su precisión es 1 (por 6.2.6.2.6 y 6.2.6.1.3 implica que no hay bits de relleno), y por lo tanto su rango es menor que el de int (por el el segundo artículo bajo 6.3.1.1.1; int tiene una precisión de al menos 15, ya que debe ser capaz de representar valores en el rango de -32767 a 32767 (ver 5.2.4.2.1)).

Dado que tanto x como la expresión (0, s.f1) tienen tipo aritmético, se realizan las conversiones aritméticas habituales (según 6.5.8.3). Como un int puede representar el rango completo de valores de s.f1 , se promueve a un int (firmado) (según 6.3.1.1.2). Luego, dado que ambos operandos son ints (firmados), el tipo real común se firma int (según 6.3.1.8) y, por lo tanto, el resultado de la comparación debe ser 0.

AFAIK, el tipo de s.f1 es unsigned int . Creo que el operador de coma es una pista falsa; esa comparación es equivalente a int y = x >= s.f1; . Aplicando las “conversiones aritméticas habituales” (C99 6.3.1.8), la x se convierte a unsigned int cuando se hace la comparación; esta conversión está bien definida (dará como resultado UINT_MAX-2 . Por lo tanto, será mayor. Por lo tanto, la respuesta debería ser 1 .

Agregaré esto aquí, es el comentario # 39 de Rajan Bhakta, aquí ,

Esta es una ambigüedad en el estándar que se ha aclarado en la próxima revisión más reciente del estándar ISO C (comúnmente conocido como C1X hasta que se ratifica) en la sección 6.3.1.1 párrafo 2. En esencia, el tipo de campo de bits (del resultado de la expresión de coma) se convierte en un int, y por lo tanto la comparación es una comparación int firmada. En esencia, el estándar C1X dice que el valor de y es 0.

Estaría agradecido si alguien puede confirmar esto.