È sempre sicuro spostare i valori di bool?

3

Mi sono imbattuto in un avvertimento Cppcheck (inconcludente), che ho erroneamente utilizzato & anziché && :

/// @param code identifies the command. Only the lower 16 bits of are being processed
int encodeCmdState(bool finished, int code, bool errorneous)
{
    return
        (finished & 1) |
        ((code & 0xffff)<<1) |
        ((err & 1)<< 17);
}

Non sono sicuro che questo codice (stile) torni indietro nei momenti in cui bool non era disponibile in C. La mia prima idea sarebbe semplicemente di rimuovere la & 1 normalizzazione dalle parti bool . Ma voglio essere sicuro, quindi ...

Sta spostando bool valori "portable" e "safe"? O, più in generale:

La implicita bool -to- int conversazione nelle espressioni aritmetiche sempre normalizza valori?

    
posta Wolf 07.01.2015 - 12:01
fonte

2 risposte

5

Secondo lo standard C ++, §4.5 annuncio. 6 (sulle promozioni integrali):

A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.

Secondo lo standard C ++, §4.7 ad. 4 (sulle conversioni integrali):

If the destination type is bool, see 4.12. If the source type is bool, the value false is converted to zero and the value true is converted to one.

Quindi un valore booleano true viene sempre convertito in 1 e un valore booleano false viene sempre convertito in 0, durante la promozione integrale e la conversione.

Ad esempio, dai un'occhiata a questo esempio semplice e ingenuo ( link ):

#include <iostream>
using namespace std;

int main() {
    bool a = true;
    bool b = false;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << boolalpha << "a = " << a << endl;
    cout << boolalpha << "b = " << b << endl;

    int c = a << 1;
    int d = b << 1;
    bool e = a << 1;
    cout << "c = " << c << endl;
    cout << "d = " << d << endl;
    cout << "e = " << e << endl;
    return 0;
}

L'output di cui sarà:

a = 1
b = 0
a = true
b = false
c = 2
d = 0
e = true
    
risposta data 07.01.2015 - 12:07
fonte
1

Poiché TommyA ha sottolineato , è sicuro, almeno in circostanze normali .

Ma è necessaria cautela se si gestiscono assegnazioni non controllate di valori di bool (dall'input), ad esempio quando si copiano porzioni di memoria (approcci IPA ingenui che usano struct s), mi aspettavo che questo fosse probabilmente un problema. Così ho creato questo semplice test case,

#include <iostream>
#include <cstring>
using namespace std;

int b2i(bool v)
{
    return v << 1;
}

int main() {
    bool v = true;
    cout << "v = " << v << endl;
    cout << "b2i(v) = " << b2i(v) << endl;

    // simulating input:
    memset(&v, -1, sizeof v);

    cout << "b2i(v) = " << b2i(v) << endl;
    return 0;
}

e provato con alcuni compilatori. In effetti, le uscite differiscono.

C ++ 14 e C ++ 4.9. 2 :

v = 1
b2i(v) = 2
b2i(v) = 2

C ++ 4.3.2 (anche in Borland 0x0564):

v = 1
b2i(v) = 2
b2i(v) = 510
    
risposta data 07.01.2015 - 15:06
fonte

Leggi altre domande sui tag