Есть ли "очень плохая вещь", которая может произойти, && = и || = использовались в качестве синтаксического сахара для bool foo = foo && bar
и bool foo = foo || bar
?
A bool
может быть только истинным
или ложным
в C ++. Таким образом, использование & =
и | =
относительно безопасно (хотя мне не особенно нравятся обозначения). Правда, они будут выполнять битовые операции, а не логические (и, следовательно, они не будут сокращать замыкание), но эти битовые операции следуют четко определенному отображению, которое фактически эквивалентно логическим операциям, при условии, что ] оба операнда относятся к типу bool
. 1
Вопреки тому, что здесь говорили другие, bool
в C ++ никогда не должен иметь другое значение, например 2
. При присвоении этого значения bool
оно будет преобразовано в true
в соответствии со стандартом.
Единственный способ получить недопустимое значение в bool
- это использовать reinterpret_cast
для указателей:
int i = 2;
bool b = *reinterpret_cast<bool*>(&i);
b |= true; // MAY yield 3 (but doesn’t on my PC!)
Но поскольку этот код в любом случае приводит к неопределенному поведению, мы можем спокойно игнорировать эта потенциальная проблема в соответствии кода C ++.
1 По общему признанию, это довольно серьезная оговорка, как показывает комментарий Энгью:
bool b = true;
b &= 2; // yields `false`.
Причина в том, что b & 2
выполняет целочисленное продвижение, так что выражение тогда эквивалентно static_cast
, что приводит к 0
, которое затем преобразуется обратно в bool
. Так что это правда, что наличие оператора && =
улучшило бы безопасность типов.
&&
и &
имеют разную семантику: &&
не будет оценивать второй операнд, если первый операнд false
. т.е. что-то вроде
flag = (ptr != NULL) && (ptr->member > 3);
безопасно, а
flag = (ptr != NULL) & (ptr->member > 3);
- нет, хотя оба операнда имеют тип bool
.
То же самое верно для & =
и | =
:
flag = CheckFileExists();
flag = flag && CheckFileReadable();
flag = flag && CheckFileContents();
будет вести себя иначе, чем:
flag = CheckFileExists();
flag &= CheckFileReadable();
flag &= CheckFileContents();