Ich habe folgendes einfaches Programm, das eine Vereinigung verwendet zwischen einer 64-Bit-Ganzzahl und der entsprechenden Byte-Array zu konvertieren:C/C++ Konvertieren eines 64-Bit-Integer-Array verkohlen
union u
{
uint64_t ui;
char c[sizeof(uint64_t)];
};
int main(int argc, char *argv[])
{
u test;
test.ui = 0xabcdefLL;
for(unsigned int idx = 0; idx < sizeof(uint64_t); idx++)
{
cout << "test.c[" << idx << "] = 0x" << hex << +test.c[idx] << endl;
}
return 0;
}
was ich als Ausgang würde erwarten ist:
test.c[0] = 0xef
test.c[1] = 0xcd
test.c[2] = 0xab
test.c[3] = 0x89
test.c[4] = 0x67
test.c[5] = 0x45
test.c[6] = 0x23
test.c[7] = 0x1
Aber was ich eigentlich:
test.c[0] = 0xffffffef
test.c[1] = 0xffffffcd
test.c[2] = 0xffffffab
test.c[3] = 0xffffff89
test.c[4] = 0x67
test.c[5] = 0x45
test.c[6] = 0x23
test.c[7] = 0x1
ich dies auf Ubuntu LTS 14.04 mit GCC zu sehen bin.
Ich habe schon seit einiger Zeit versucht, mich damit zu beschäftigen. Warum werden die ersten 4 Elemente des char-Arrays als 32-Bit-Ganzzahlen angezeigt, denen 0xffffff vorangestellt ist? Und warum nur die ersten 4, warum nicht alle?
Interessanterweise werden die richtigen Werte geschrieben, wenn ich das Array verwende, um in einen Stream zu schreiben (was der ursprüngliche Zweck der ganzen Sache war). Aber das Vergleichen des Array-Zeichens durch char führt offensichtlich zu Problemen, da die ersten 4 Zeichen nicht gleich 0xef, 0xcd usw. sind.
umgewandelt als '(char *)' und dann lesen 4 Bytes ...? – SteJ
Keine Änderung. Außerdem kann ich das Zeichen immer mit 0x000000ff maskieren, um die erwarteten Werte zu erhalten. Ich bin nur an dem Grund interessiert, der zu diesem Verhalten geführt hat. – tickferno
Anscheinend hat Ihre Implementierung Zeichen signiert. Normale Integer-Promotion wird vorzeichenerweitert. – ewd