Se la dimensione di byte
è solo un byte, perché printf()
si comporta come se fosse quattro byte?Perché printf applica un char a 8 bit a 32 bit?
risposta
Formalmente, il programma presenta un comportamento indefinito: %x
specifica di formato si aspetta un argomento di tipo unsigned int
, ma si sta passando un int
, come spiegato di seguito (hat tip @R). In pratica ciò è innocuo con le moderne macchine a complemento a due, poiché int e unsigned hanno layout di bit compatibili. Ma ancora, tecnicamente, questo è un comportamento indefinito e sarebbe una buona idea ripararlo, come in printf("%x\n", (unsigned)byte);
.
Le regole per il passaggio di parametri alle funzioni variadic affermano che tutti i tipi integrali di dimensioni inferiori a int vengono promossi a int. Altrimenti, come lo sarebbe printf
, vedendo %x
, se estrarre uno o quattro byte dallo stack? Dallo standard:
5.2.2p7:
Quando non esiste un parametro per un dato argomento, l'argomento viene passato in modo tale che la funzione di ricezione può ottenere il valore dell'argomento invocando va_arg(18.10)...
Se l'argomento ha tipo integrale o di enumerazione che è soggetta alle promozioni integrali(4.5),
o un tipo virgola mobile che è soggetta al punto promozione galleggiante(4.6),
il valore dell'argomento viene convertito nel tipo promosso prima della chiamata.
Questo è il modo in cui il char
si trasforma in un int
. Non è specificato se char
è firmato o non firmato, ma a quanto pare, sulla piattaforma che si utilizza è un tipo firmato. In questo modo viene esteso il segno quando viene promosso a int
. 0xff
è (char)-1
, e 0xffffffff
è (int)-1
.
Ti capita di avere il riferimento standard a quelle regole? –
5.2.2p7 Quando non ci sono parametri per un dato argomento, l'argomento viene passato in modo tale che la funzione ricevente possa ottenere il valore dell'argomento invocando va_arg (18.10) ... Se l'argomento ha tipo integrale o di enumerazione che è soggetto alle promozioni integrali (4.5), o un tipo a virgola mobile che è soggetto alla promozione in virgola mobile (4.6), il valore dell'argomento viene convertito nel tipo promosso prima della chiamata. –
Ho capito, molte grazie –
Un char
è firmato a 8 bit. Il formato "%x\n"
dice di stampare un numero intero. Quindi il valore di byte
è esteso a un numero intero. Poiché un char
di 0xff
è, in tale contesto, un valore a 8 bit di -1
, printf
sta stampando solo il valore intero esadecimale di un -1
, che è ffffffff
.
Su questa piattaforma, plain 'char' è una quantità a 8 bit con segno. Lo standard C dice esplicitamente che il semplice 'char' è firmato o non firmato è un dettaglio definito dall'implementazione. –
penso che sia a causa di integer promotion
Un buon post sul blog su questo concetto: http://www.idryman.org/blog/2012/11/21/integer-promotion/
Hai invocato un comportamento indefinito passando il tipo di argomento sbagliato printf
. Il %x
specificatore richiede un argomento di tipo unsigned int
, ma è passato (a causa di promozioni di default) un firmato int
. Questo è validamente valido se il valore dell'argomento int
firmato è non negativo, ma sul proprio sistema, è normale che char
sia un tipo firmato, quindi byte
contiene il risultato dell'applicazione di una conversione definita dall'implementazione su 0xff
; il solito risultato di questa conversione è -1.
- 1. C - Come verificare se 8 bit sono a 32 bit?
- 2. Perché MSBuild a 64 bit carica estensioni a 32 bit?
- 3. Elementi intrinseci SSE: Converti i float a 32 bit in interi a 8 bit UNSIGNED
- 4. Lettura a 16 bit da un registro a 32 bit
- 5. Perché l'applicazione a 32 bit non accede all'hive del Registro di sistema a 32 bit?
- 6. Operatore bit a bit per ottenere byte da 32 bit
- 7. Perché __sync_add_and_fetch funziona per una variabile a 64 bit su un sistema a 32 bit?
- 8. Compilare binario a 32 bit su sistema a 64 bit
- 9. Mappare un float a 32 bit su un intero a 32 bit
- 10. typecasting implicito in C (conversione a 32 bit senza segno a 8 bit u INT)
- 11. Un collegamento EXE a 64 bit contro DLL a 32 bit?
- 12. Esegui libreria a 32 bit su iPhone 5s 64 bit
- 13. Accesso a file da 2,3,4 GB in processo a 32 bit su Windows a 64 bit (o 32 bit)
- 14. Build 32-bit con llvm-gcc a 64 bit
- 15. Perché std :: size_t 4 byte su sistemi a 32 bit quando unsigned long long è 8 byte su entrambi i sistemi a 32 bit e 64 bit?
- 16. Determinazione dell'architettura a 32/64 bit nell'assemblaggio
- 17. windows 7 PATH errato a 64 bit durante il caricamento di una libreria a 32 bit per 32 bit exe
- 18. Perché un campo a 8 bit ha endianness?
- 19. MapViewOfFile condiviso tra processi a 32 bit e 64 bit
- 20. Converti 12 bit int a 16 o 32 bit
- 21. Hash 32 bit int a 16 bit int?
- 22. Inno Setup installazione dll a 32 bit e 64 bit
- 23. Perché è più veloce a 64 bit rispetto a 32 bit?
- 24. Compilando 32 bit Assembler su ubuntu a 64 bit
- 25. Come convertire l'int firmato a 32 bit int a 32 bit senza segno int?
- 26. Istruzioni di caricamento in attesa a 32 bit IR (architettura a 32 bit in stile RISC)
- 27. Inversione bit tramite bit a bit
- 28. sostituire byte a 32 bit numero
- 29. prestazioni a 32 bit vs 64 bit aritmetica
- 30. Port 32 bit driver di Windows a 64 bit Windows
google "promozione intera" –
Leggi la mia risposta in basso –
Ho appena ricevuto un collegamento [Deep C: Integer Promotion] (http://www.idryman.org/blog/2012/11/21/integer-promotion/) spiega quello che stavo dicendo La sua implementazione dipende. –