Почему в C нет оператора логического присваивания?

Мне нужно было закодировать оператор в форме

a = a || expr;

, где expr должен быть оценен, а результат должен быть присвоен a , если a есть не задано. это основано на возможностях короткого замыкания логического ИЛИ.

Конечно, более коротким способом написать выше было бы

a ||= expr;

, но (к моему удивлению) C не имеет операторов логического назначения.

Так что мой вопрос двоякий. Во-первых, есть ли более короткий способ написать первое утверждение в стандарте C (троичный оператор еще хуже - a = a? A: expr требует, чтобы я изложил a трижды) ,

Во-вторых, почему в C нет логических назначений? Возможные причины, о которых я мог подумать:

  • это затрудняет анализ грамматики?
  • есть некоторая тонкость в обработке короткого замыкания для этих случаев?
  • это считалось излишним (но разве это не аргумент против ВСЕХ назначений операторов?)

РЕДАКТИРОВАТЬ

Пожалуйста, разблокируйте этот вопрос, потому что:

  • Вопрос, с которым он был связан (как предполагаемый дубликат), НЕ ОТВЕЧЕН. (Принятый) ответ на этот вопрос гласит, что || = отсутствует, поскольку дублирует функциональность | = . Это неправильный ответ. | = не закорачивает.

  • C и C ++ НЕ являются одинаковыми языками. Я хочу знать, почему у С этого нет. Фактически, тот факт, что производные языки, такие как C ++ и, в частности, Java (которые не страдали от проблем унаследованного кода, как было предложено в Edmund ') s ответ) делает вопрос еще более интересным.

РЕДАКТИРОВАТЬ 2

Теперь кажется, что мое первоначальное намерение было неверным. В утверждении a = a || expr (где a является целым, а expr возвращает интегральное значение, сначала оба a и expr будут неявно преобразованы в «булево», а затем «булево» значение будет присвоено a . Это будет неверно - интегральное значение будет потеряно. Спасибо, Дженс и Эдмунд.

Итак, для первой части вопрос, правильные пути, а не альтернативы :), чтобы закодировать мое намерение было бы:

if (!a) a = expr;

или

a = a ? a : expr;

они должны быть оптимизированы одинаково (я думаю), хотя лично я предпочел бы первый (потому что он имеет один меньше a для ввода).

Однако, вторая часть вопроса все еще остается. Аргументы, высказанные Йенсом и Эдмундом о неоднозначности в a || = expr , одинаково хорошо применимы и к a = a || выражение . случай назначения можно просто рассматривать как нормальный:

  • преобразовать a в логическое значение
  • , если оно истинно, значение всего выражения становится равным логическому значению a
  • в противном случае оценивают expr , преобразуют результат в логическое значение, присваивают a и возвращают его

Представленные выше шаги кажутся одинаковыми как для назначения, так и для обычного случая.

32
задан Lundin 6 July 2017 в 14:04
поделиться

1 ответ

Думаю, простой ответ в том, что || - это булев оператор: а в Си "булево" - это 0 или 1. Операнды неявно преобразуются в булевы (я не проверял, так ли это на самом деле в спецификации, но именно так ведет себя C), и результатом является булево число.

Изменение семантики для поддержки этого паттерна может быть вполне осуществимо - пока кто-то не положится на ||, делая то, что он всегда делал.

3
ответ дан 27 November 2019 в 21:17
поделиться
Другие вопросы по тегам:

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