c gcc bit-manipulation bit-shift unspecified-behavior

¿Es "-1>> 5" un comportamiento no especificado en C?



gcc bit-manipulation (2)

C11 §6.5.7 Párrafo 5:

El resultado de E1 >> E2 es E1 posiciones de bit E2 desplazadas a la derecha. Si E1 tiene un tipo sin signo o si E1 tiene un tipo firmado y un valor no negativo, el valor del resultado es la parte integral del cociente de E1 / 2*^E2 . Si E1 tiene un tipo firmado y un valor negativo, el valor resultante está definido por la implementación.

Pero, el documento de referencia viva64 dice:

int B; B = -1 >> 5; // unspecified behavior

Ejecuté este código en GCC y siempre da una salida -1 .

Por lo tanto, el estándar dice que "si E1 tiene un tipo firmado y un valor negativo, el valor resultante está definido por la implementación" , pero ese documento dice que -1>>5; es un comportamiento no especificado .

Entonces, es -1>>5; comportamiento no especificado en C? ¿Cual es correcta?


Ambos son correctos. El comportamiento definido de implementación es un tipo particular de comportamiento no especificado.

Citando la sección 3.4.1 del estándar C que define "comportamiento definido por la implementación":

1 comportamiento definido por la implementación

comportamiento no especificado donde cada implementación documenta cómo se realiza la elección

2 EJEMPLO Un ejemplo de comportamiento definido por la implementación es la propagación del bit de orden superior cuando un entero con signo se desplaza hacia la derecha.

De la sección 3.4.4 definición de "comportamiento no especificado":

1 comportamiento no especificado

uso de un valor no especificado u otro comportamiento donde esta Norma Internacional proporciona dos o más posibilidades y no impone requisitos adicionales sobre los cuales se elige en cualquier caso

2 EJEMPLO Un ejemplo de comportamiento no especificado es el orden en que se evalúan los argumentos para una función.

En cuanto a GCC, siempre obtendrá la misma respuesta porque la operación está definida por la implementación. Implementa el desplazamiento a la derecha de los números negativos a través de la extensión del signo

De la documentación de GCC :

Los resultados de algunas operaciones bit a bit en enteros con signo (C90 6.3, C99 y C11 6.5).

Los operadores bit a bit actúan en la representación del valor, incluidos los bits de signo y de valor, donde el bit de signo se considera inmediatamente por encima del bit de valor de mayor valor. Firmado >> actúa sobre números negativos por extensión de signo.

Como una extensión del lenguaje C, GCC no usa la latitud dada en C99 y C11 solo para tratar ciertos aspectos de << firmado como indefinido. Sin embargo, -fsanitize=shift (y -fsanitize=undefined ) diagnosticará dichos casos. También se diagnostican cuando se requieren expresiones constantes.


El "comportamiento no especificado" y la "implementación definida" no son contradictorios. Simplemente significa que el estándar C no especifica qué debe suceder y que varias implementaciones pueden hacer lo que consideran "correcto".

Ejecutarlo varias veces en un compilador y obtener el mismo resultado solo significa que ese compilador en particular es consistente. Puede obtener resultados diferentes en un compilador diferente.