En C, puede convertir tanto tipos de datos simples como int
, float
, como punteros a estos.En C, si lanzo y desreferencia un puntero, ¿qué importa primero?
Ahora habría supuesto que si quiere convertir de un puntero a un tipo al valor de otro tipo (por ejemplo, de *float
a int
), el orden de conversión y desreferenciación no tiene importancia. Es decir. que para una variable float* pf
, tiene (int) *pf == *((int*) pf)
. Algo así como la conmutatividad en matemáticas ...
Sin embargo, este no parece ser el caso. Escribí un programa de pruebas:
#include <stdio.h>
int main(int argc, char *argv[]){
float f = 3.3;
float* pf = &f;
int i1 = (int) (*pf);
int i2 = *((int*) pf);
printf("1: %d, 2: %d\n", i1, i2);
return 0;
}
y en mi sistema la salida es
1: 3, 2: 1079194419
Así que echando el puntero parece funcionar de manera diferente desde la fundición del valor.
¿Por qué es eso? ¿Por qué la segunda versión no hace lo que creo que debería?
¿Y depende de esta plataforma, o estoy de alguna manera invocando el comportamiento indefinido?
Suele manifestarse como una violación de "alias estricto" que da como resultado la lectura de datos incorrectos o la ausencia de datos, al menos en gcc moderno. –
No se manifiesta, es una violación, y sí, gcc generalmente lo advierte al respecto (no atrapa todos los casos, afaik). Dije que no está definido, solo le expliqué lo que sucede en su caso: puede verificarlo fácilmente, p. con un pequeño fragmento de rubí '[3.3] .pack (" f "). desempaquetar (" I ") => [1079194419]' – etarion
Solo para información, mi programa de ejemplo anterior compila sin advertencias bajo '-Wall', así que sí, gcc no detecta todos los casos ;-). – sleske