Es muy probable que no intente cambiar por una gran cantidad de bits.
INT_MAX
en su sistema es probablemente 2**31-1
, o 0x7fffffff
(estoy usando **
para denotar exponenciación). Si ese es el caso, entonces en la declaración:
int b = 0x80000000;
(que faltaba un punto y coma en la pregunta, por favor copiar y pegar su exacta código) la constante 0x80000000
es de tipo unsigned int
, no int
. El valor se convierte implícitamente en int
. Como el resultado está fuera de los límites de int
, el resultado está definido por la implementación (o, en C99, puede generar una señal definida por la implementación, pero no conozco ninguna implementación que lo haga).
La forma más común de hacerlo es reinterpretar los bits del valor sin signo como un valor firmado como complemento de 2. El resultado en este caso es -2**31
o -2147483648
.
lo tanto, el comportamiento no está definido porque estás cambiando por valor igual o superior a la anchura del tipo int
, no está definida porque estás cambiando de un (muy grande) valor negativo.
No es que importe, por supuesto; undefined no está definido.
NOTA: Lo anterior supone que int
es de 32 bits en su sistema. Si int
es más ancho que 32 bits, la mayor parte no se aplica (pero el comportamiento aún no está definido).
Si realmente quería intentar cambiar por 0x80000000
trozos, podría hacerlo de esta manera:
unsigned long b = 0x80000000;
unsigned long a = 1 >> b; // *still* undefined
unsigned long
se garantiza que sea lo suficientemente grande como para contener el valor 0x80000000
, por lo que evitar que parte del problema . Por supuesto, el comportamiento del cambio es tan indefinido como en el código original, ya que 0x80000000 es mayor o igual que el ancho de unsigned long
. (A menos que su compilador tiene un muy grande unsigned long
tipo, pero sin compilador del mundo real que lo hace.)
La única manera de evitar un comportamiento indefinido no es hacer lo que usted está tratando de hacer.
Es posible
, pero es poco probable que sea probable,
que el comportamiento del código original no está indefinido. Esto sólo puede ocurrir si la conversión definida por la implementación de 0x80000000
de unsigned int
a int
se obtiene un valor en el rango 0 .. 31. Si int
es menor que 32 bits, es probable que el rendimiento 0.
Técnicamente, es un comportamiento indefinido, ya que está desplazando más del ancho del tipo (que gcc debe informar en una advertencia). –
A menos que lo lances, ¿no sería eso pedirle que cambie por -1? – Marvo
Además, parece que 'gcc' respeta por completo el espíritu de UB, dando diferentes resultados" incorrectos "según las condiciones (http://gcc.gnu.org/ml/gcc/2004-11/msg01131.html) –