2011-11-11 9 views
5

Secondo PC-lint, la seguente dichiarazione non sarà mai TRUE:Questa istruzione C/C++ if() può mai essere valutata su TRUE?

if((variable & 0x02) == 1) 

Sto usando un compilatore C per sistemi embedded che valuta a TRUE ogni volta che viene impostato il bit corrispondente in variable. Immagino che il compilatore stia facendo un confronto TRUE/FALSE di entrambi i lati dello == invece di confrontare i numeri risultanti. In altre parole, ogni volta che l'espressione (varable & 0x02) non è zero (ad esempio TRUE), la dichiarazione sarà anche TRUE, poiché il valore 1 is also TRUE (non zero).

Non so se gli standard C/C++ definiscono chiaramente come dovrebbe comportarsi un compilatore in questo caso. Esistono esperti C/C++ che possono rispondere a questa domanda sulla base di ciò che dicono gli standard (ad esempio C90, C99, ecc.)?

P.S .: Nella dichiarazione precedente, "variabile" è un carattere senza segno.

+4

Qual è il 'tipo di variable'? –

+2

Potresti per favore chiamare questo compilatore? Un mio amico crea una collezione di bug di compilatori dispari. – blaze

+1

È possibile che il tuo codice reale abbia una doppia e commerciale (ad esempio "var && 0x02")? Ciò spiegherebbe il compilatore valutandolo come vero. – tinman

risposta

11

PC-lint è giusto. Supponendo che var sia una variabile intera, l'espressione var & 0x02 può valutare due valori: 0 e 2. Non sarà mai uguale a 1, che è ciò che sta testando l'istruzione if.

Per espandere su questo, l'operatore di uguaglianza viene applicato a due valori interi. Ciò che conta è se entrambi gli operandi valutano lo stesso numero, non se entrambi siano contemporaneamente "veri" o "falsi".

per verificare se il bit 1 è impostato, si potrebbe usare:

if (variable & 0x02) { 
    ... 
} 

Dato che il compilatore si comporta il modo in cui si dice che fa, è chiaramente non conforme. Tuttavia, gestirà quasi certamente if (variable & 0x02) correttamente. La mia raccomandazione sarebbe quella di correggere il codice in modo che non si interrompa in silenzio se si dovesse mai cambiare compilatori.

Infine, la situazione è diversa se: (1) il codice è C++ e non C; e (2) variable è l'istanza di una classe; e (3) la classe sovraccarica gli operatori in questione. In tal caso, il comportamento dipende da ciò che gli operatori sovraccarichi effettivamente fanno.

+0

Questo perché '0x02' ha un solo bit impostato nel suo pattern di bit. –

+4

Questo non è il caso in C++ a causa della presenza di operatori sovraccaricati. – bdonlan

+2

Idealmente dovresti sempre usare il modello 'if ((variable & CONST) == CONST)' se vuoi verificare se tutti i bit in una data maschera sono impostati. – tylerl

6

In C++, questo può valutare un valore vero se (e solo se) variable è un'istanza di una classe con un operator& sovraccarico che non è conforme alla normale semantica AND bit.

In C, questa condizione sarà sempre falsa. §6.5.10 definisce la semantica del bit operatore, ed è abbastanza semplice e al punto:

  4. Il risultato della & operatore binario è l'AND bit a bit degli operandi (cioè, ogni bit in il risultato viene impostato se e solo se ognuno dei bit corrispondenti negli operandi convertiti è impostato ).

E 'chiaro che il risultato non può essere 1, come 1 bit non è impostato sul valore convertito dell'operando di destra-lato (cioè, 0x02).

Naturalmente, se il comportamento non definito è stato invocato in un determinato momento nel passato del programma (o in fase di compilazione!), Allora tutto può succedere. Esclusa questa possibilità, tuttavia, il compilatore non è conforme. Cioè, rotto. Questo, purtroppo, è estremamente comune su compilatori dispari incorporati. Se sei fortunato, potresti persino essere in grado di segnalare il bug e correggerlo.

4

Non penso che lo standard definisca qualcosa su questo problema molto specifico e insolito. Come detto da AIX, questa affermazione non può mai essere vero perché (in binario):

XXXX XXXX -> variable 
0000 0010 -> 0x02 
--------- AND 
0000 00X0 -> result 

(semplificando a 8-bit tipi)

Così i vostri solo i risultati possono essere 0000 0010 (che è 2) o 0000 0000 (che è 0).

+1

Grazie per la rappresentazione visiva :) – AntonioCS

0

Fondamentalmente, il lint è proprio qui. Almeno su qualsiasi piattaforma che conosco, la condizione produrrà false. Guarda la rappresentazione bit dei numeri: x & 2 (0010) sarà sempre uguale a zero o 2 (0010) e quindi diverso da 1 (0001) per ogni intero x.

1

Per C, la risposta è no.

Il C standard dice di & (6.5.10):

Il risultato della & operatore binario è l'AND bit a bit degli operandi (cioè ogni bit il risultato viene impostato se e solo se ognuno dei bit corrispondenti negli operandi convertiti è impostato su ).

Poiché nel 2 solo il bit 1 è impostato, il valore dell'espressione può essere impostato solo il bit 1. Può assumere altri valori di 2 e 0. 2 Né né 0 può confrontare uguale a 1.

Le rappresentazioni dei bit degli interi sono definite in 6.2.6.2 (per valori non negativi nel solito modo).

0

Consideriamo il valore binario di 2

02 = 0010 (say a 4 bit number) 

e il valore binario di 1 è

01 = 0001 

minimamente significat di 2 è sempre zero che è il bit più a sinistra è 0 SO
L'operazione & (e) con 0 non dà mai 1 quindi possiamo dire che non può mai essere uguale a 1

 0 0 => 0 
     0 1 => 0 
     1 1 => 1 

Nota: & indica il bit saggio e il funzionamento

2 - 0010 
    3 - 0011 
     0010 

Quindi l'uscita con xx & 2 sarà 0 o 2.

Problemi correlati