Почему C++ не имеет && = или || = для булевских переменных?

Есть ли "очень плохая вещь", которая может произойти, && = и || = использовались в качестве синтаксического сахара для bool foo = foo && bar и bool foo = foo || bar?

115
задан Kache 21 March 2010 в 19:34
поделиться

2 ответа

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 (b) & 2 , что приводит к 0 , которое затем преобразуется обратно в bool . Так что это правда, что наличие оператора && = улучшило бы безопасность типов.

69
ответ дан 24 November 2019 в 02:27
поделиться

&& и & имеют разную семантику: && не будет оценивать второй операнд, если первый операнд 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();
44
ответ дан 24 November 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: