私は誤って&
ではなく&&
を使用したというCppcheck警告(決定的な警告)につまずきました。
/// @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);
}
このコード(スタイル)がbool
がCで利用できなかった時代に戻ったかどうかはわかりません。私の最初のアイデアは、bool
の部分から& 1
の正規化を単に取り除くことです。でも確かにしたいので...
シフトbool
値は「ポータブル」および「セーフ」ですか?または、より一般的には:
implicitbool
- to -int
会話式の算術式always normalize値はありますか?
C++標準に従って、§4.5広告。 6(統合プロモーションについて):
Bool型のprvalueはint型のprvalueに変換でき、falseはゼロになり、trueは1になります。
C++標準に従って、§4.7ad。 4(積分変換について):
宛先タイプがブールの場合は、4.12を参照してください。ソースタイプがブールの場合、値falseはゼロに変換され、値trueは1に変換されます。
したがって、整数の昇格と変換中に、ブール値true
は常に1に変換され、ブール値false
は常に0に変換されます。
例として、この単純で素朴な例( http://ideone.com/kgxrTW )を見てください。
#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;
}
その出力は次のようになります:
a = 1
b = 0
a = true
b = false
c = 2
d = 0
e = true
TommyAが指摘 のように、少なくとも通常の状況は安全です。
しかし、(入力から)bool
値のチェックされていない割り当てを処理する場合は注意が必要です。たとえば、メモリ部分をコピーする場合(ナイーブIPCはstruct
sを使用します) 、これが問題になる可能性があると思ったので、この簡単なテストケースを作成しました。
#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;
}
いくつかのコンパイラで試してみました。実際、出力は異なります。
v = 1
b2i(v) = 2
b2i(v) = 2
C++ 4.3.2(Borland 0x0564でも):
v = 1
b2i(v) = 2
b2i(v) = 510