Il problema è qui:
char charray[] = {0xAA, 0x00, 0x02};
Il tipo char ha signedness implementazione definita, il che significa che in alcuni sistemi sarà equivalente a signed char
. Un signed char
può solo memorizzare valori fino a 0x7F e l'MSB verrà trattato come un bit di segno. Questo è ciò che accade nel tuo caso, 0xAA
viene convertito in un valore firmato di -86
(è definito dall'implementazione quale valore ottiene, sto assumendo il complemento a due).
Il segno viene quindi mantenuto nell'espressione 0xAA == ch
, perché ch
viene quindi promosso per digitare int
e il segno viene mantenuto. Significa che comparirai effettivamente a 0xAA == -86
che è falso.
Per evitare errori di questo tipo, utilizzare sempre uint8_t
quando si effettua qualsiasi forma di aritmetica a livello di byte.
No, in realtà sta confrontando '0xAA == -86'. Non necessariamente la stessa cosa di '0xAA == 0xFFFFFFAA', a seconda di come le promozioni implicite risultano sul sistema specifico. – Lundin
@Lundin se vuoi essere schizzinoso, in realtà sta confrontando '0xAA == (signed char) 0xAA' che è persino diverso dal momento che la conversione è definita dall'implementazione. – ouah
Il mio punto è: finché l'operando di sinistra (il letterale int) è un 'int', il char passerà attraverso la promozione intera (la regola di promozione intera) e rimarrà firmato. Ma se il letterale era un tipo senza segno, ci sarebbe anche il bilanciamento (solite conversioni aritmetiche) e l'operando di destra verrebbe convertito anche in tipo senza segno. Nel qual caso si finirebbe per essere uguale a '0xFFFFFFAAu'. Ma questo non accade in questo specifico esempio. – Lundin