Когда является правым выражением bool a | = mayRun (); выполняется?

Предположим, фрагмент кода

bool a;
a = true;
a |= mayRun();

a = false;
a |= mayRun();

в каком случае выполняется mayRun ()?

Все объяснения говорят мне, что
a |= b;
эквивалентно
a = a | b;

Но это не может быть таким же, как пример
arr[i++] |= b;
указывает на то.

1

Решение

Это всегда выполняется. Обратите внимание, что a |= b это действительно сокращение для a = a | b (только оценка a один раз). В частности, это не сокращение для a = a || b,

Это означает, что он не обеспечивает короткого замыкания логических операторов, поэтому b всегда оценивается.

Используя эти сокращенные формы назначения с bool переменные опасны именно потому, что семантика неочевидна. &= на самом деле еще хуже. Сравните это:

int two() { return 2; }

int main()
{
bool b = true;
b = b && two();
assert(b);  //OK
}

с этим:

int two() { return 2; }

int main()
{
bool b = true;
b &= two();
assert(b);  //FAILS!!
// b &= two(); was actually b = 1 & 2, which is 0 !
}

Короче говоря, избегайте использования |= а также &= с логическими переменными.

5

Другие решения

Он всегда будет выполняться, потому что короткое замыкание не применимо к побитовым операциям (применимо только к логическим операциям, таким как && а также ||).

Обратите внимание, что это неправильное представление может привести к неприятным ошибкам — разработчик предположит, что существует короткое замыкание, но его нет, и все части выражения выполняются всегда, и это изменяет логику программы.

7

в каком случае mayRun() выполняется?

Это всегда будет выполнено.

Возможно, вы ожидали |= выполнить короткое замыкание, но это не так: это происходит только с логический операторы && а также ||, когда результат может быть определен только из первого операнда. Там нет логических составных операторов присваивания, таких как ||=, поэтому короткое замыкание никогда не произойдет в выражении присваивания.

Все объяснения говорят мне, что a |= b; эквивалентно a = a | b;

Почти; но все объяснения, которые вы читали, упустили важную деталь.

Но это не может быть таким же, как пример arr[i++] |= b; указывает на то.

Действительно, есть разница, как указано в C ++ 11 5.17 / 7:

Поведение выражения формы E1 op = E2 эквивалентно E1 = E1 op E2 за исключением того, что E1 оценивается только один раз.

0
По вопросам рекламы [email protected]