Ho il seguente semplice programma che utilizza un'unione per la conversione tra un intero a 64 bit e la corrispondente matrice di byte:C/C++ Convertire un intero a 64 bit char matrice
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;
}
Quello che ci si aspetterebbe come output è:
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
Ma quello che in realtà ottengo è:
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
sto vedendo questo su Ubuntu LTS 14.04 con GCC.
Ho cercato di capire da un po 'di tempo. Perché i primi 4 elementi dell'array char vengono visualizzati come numeri interi a 32 bit, con 0xffffff aggiunto a loro? E perché solo i primi 4, perché non tutti loro?
È interessante notare che quando uso la matrice per scrivere su un flusso (che era lo scopo originale dell'intera cosa), vengono scritti i valori corretti. Ma confrontare l'array char con char porta ovviamente a problemi, poiché i primi 4 caratteri non sono uguali a 0xef, 0xcd e così via.
cast come '(char *)' e quindi leggere 4 byte ...? – SteJ
Nessun cambiamento. Inoltre, posso sempre mascherare il carattere con 0x000000ff per ottenere i valori previsti. Sono solo interessato alla ragione di questo comportamento. – tickferno
Apparentemente la tua implementazione ha firmato caratteri. La promozione di interi normale verrà firmata in estensione. – ewd