In C können Sie beide einfachen Datentypen wie int
, float
und Zeiger auf diese werfen.In C, wenn ich einen Zeiger werfen und dereferenzieren, ist es wichtig, welche ich zuerst mache?
Nun würde ich angenommen haben, dass, wenn Sie von einem Zeiger zu einem Typ auf den Wert eines anderen Typs (z. B. von *float
zu int
) konvertieren möchten, die Reihenfolge der Casting und Dereferenzierung spielt keine Rolle. I.e. das für eine Variable float* pf
, haben Sie (int) *pf == *((int*) pf)
. Ähnlich wie Kommutativität in Mathematik ...
Dies scheint jedoch nicht der Fall zu sein. Ich schrieb ein Testprogramm:
#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;
}
und auf meinem System die Ausgabe
1: 3, 2: 1079194419
So den Zeigers Gießen scheint anders zu arbeiten aus dem Wert Gießen.
Warum ist das? Warum macht die zweite Version nicht das was ich denke?
Und ist das plattformabhängig, oder rufe ich irgendwie undefiniertes Verhalten auf?
Normalerweise manifestiert es sich als eine "strikte Aliasing" Verletzung, die zum Lesen der falschen Daten oder gar keine Daten, zumindest auf modernen gcc führt. –
Es zeigt sich nicht in, es ist eine Verletzung, und ja, GCC warnt Sie normalerweise davor (es fängt nicht alle Fälle, afaik). Ich sagte, es ist nicht definiert, ich habe nur erklärt, was in seinem Fall passiert - Sie können das leicht überprüfen, z. mit einem kleinen Ruby Snippet '[3.3] .pack (" f "). auspacken (" I ") => [1079194419]' – etarion
Nur zur Information, mein Beispielprogramm oben kompiliert ohne Warnungen unter '-Wall', also ja, Gcc fängt nicht alle Fälle ;-). – sleske