2015-04-01 14 views
10

Se un programma C++ applica l'operatore bitwise-not (~) a un valore booleano, viene richiamato il comportamento non definito?L'uso dell'operatore bitwise non (~) sui valori booleani richiama il comportamento non definito?

E.g. il seguente programma è ben definito?

bool f = false; 
bool f2 = ~f; // is f2 guaranteed to be true, or is this UB? 
bool t = true; 
bool t2 = ~t; // is t2 guaranteed to be false, or is this UB? 

(Sì, so che c'è un operatore di che è più adatto a questo genere di cose;! Per scopi di questa domanda ci sarà ignorare la sua esistenza;))

+3

Sto supponendo che '~' promuova l'argomento di 'int' prima di fare qualsiasi cosa, quindi ~ 0 converrebbe in' true'. Non posso essere sicuro al 100% senza guardare. – chris

+0

@chris, hai ragione. –

+0

UB fa 'bool b = 13;' [o qualcosa del genere]? –

risposta

8

5.3.1/10 L'operando di ~ avrà integrale o senza ambito tipo di enumerazione; il risultato è il complemento del suo operando. Le promozioni integrali vengono eseguite. [emphasis mine]

4.5/6 Un valore di tipo bool può essere convertito in un valore di tipo int, con false diventa zero e true diventando uno.

4.5/7 Queste conversioni sono chiamate promozioni integrali.

Così ~false è un int con un modello di bit costituita da tutti quelli - (. Come richiesto dalla 3.9.1/7) complemento a uno di una sequenza di bit che rappresenta 0, vale a dire tutti zeri Analogamente, è un ~trueint è il complemento della rappresentazione bit di 1, ovvero tutti quelli con il bit zero meno significativo. Entrambi questi valori verranno valutati su true in contesto booleano.

+0

@MattMcNabb Da dove viene questo standard? In realtà stavo cercando quel testo e, purtroppo, non ci sono riuscito. C'è una formulazione di questo effetto in C99 ** 6.2.6.2 ** - forse si potrebbe sostenere che questa formulazione è incorporata nello standard C++ come riferimento, ma suona come un argomento piuttosto debole. Mi manca qualcosa di ovvio? –

+0

@MattMcNabb Ah, giusto. "Pure binary numeration system" è il termine dell'arte che ho dimenticato. Permettimi di aggiornare la risposta. –

+1

Immagino ci sia un po 'di spazio per argomentare che lo zero negativo potrebbe essere una rappresentazione alternativa di '0', nel complemento uno –

1
bool t = true; 
bool t2 = ~t; // is t2 guaranteed to be false, or is this UB? 

suppongo non è garantito, vedendo come

bool b = true; 
    bool b1 = ~b; 
    cout << b1; 

emette un "vero"

suppongo che ha a che fare con il fischio rappresentazione snella ... se è un byte, allora 00000001 negherà a 11111110 che non è zero. La promozione potrebbe anche essere in gioco, ma è la stessa melodia.

La chiave qui è "bitwise" non "logical". Quindi non ci si dovrebbe aspettare che i due corrispondano, a meno che la rappresentazione booleana non sia un singolo bit.

Comportamento facilmente definito.

3

Gli operatori aritmetici eseguono le promozioni integrali sul proprio operando. Specificamente [expr.unary.op]/9 dice che questo accade anche per ~.

Quindi ~t è lo stesso di ~1. Questo dà un numero intero non zero valido.

conversioni intero-to-bool sono definiti da [conv.bool]:

valore zero, il valore del puntatore nullo, o nullo valore del puntatore membro è convertita in false; qualsiasi altro valore viene convertito in true

così bool t2 = ~t; cede t2 == true. Non c'è un comportamento indefinito.


~f è lo stesso di ~0. Nel complemento a 2, ~0-1, quindi avremo f2 == true.

In complemento a 1: se esistesse un sistema C++ che utilizza il complemento a 1, l'effetto di ~0 non è chiaro.