Мне нужно было закодировать инструкцию формы
a = a || expr;
где expr
должен быть оценен, и результат должен быть назначен a
, если if a
не установлен. это зависит от логических или коротких замыканий.
Более короткий способ написать выше, конечно, будет
a ||= expr;
но (к моему удивлению) C не имеет операторов логического присваивания.
Итак, мой вопрос двоякий. Во-первых, существует более короткий способ написать первое утверждение в стандарте C (тернарный оператор еще хуже - a = a ? a : expr
требует, чтобы я произносил a
трижды).
Во-вторых, почему в C нет логических назначений? Возможные причины, о которых я мог подумать, следующие:
- это усложняет анализ грамматики?
- Есть ли какая-то тонкость в обработке короткого замыкания для этих случаев?
- он считался лишним (но разве это не аргумент против ВСЕХ назначений операторов?)
EDIT
Пожалуйста, откройте этот вопрос, потому что:
-
Вопрос, с которым он был связан (как предполагаемый дубликат), НЕ ОТВЕТИЛ. Ответ на этот вопрос (принятый) гласит, что
||=
отсутствует, поскольку дублирует функциональность|=
. Это неправильный ответ.|=
не замыкается. -
C и С++ не являются одними и теми же языками. Я хочу знать, почему у C его нет. Фактически, тот факт, что производные языки, такие как С++ и, в частности, Java (которые не страдают от проблем с устаревшим кодом, как это было предложено в ответе Эдмунда), делает вопрос еще более интересным.
РЕДАКТИРОВАТЬ 2
Теперь кажется, что мое первоначальное намерение было неправильным. В заявлении a = a || expr
(где a
является интегралом, а expr
возвращает целочисленное значение, сначала оба a
и expr
будут неявно преобразованы в "booleans", а затем будет присвоено значение "boolean" до a
. Это будет некорректно - интегральное значение будет потеряно. Спасибо, Йенс и Эдмунд.
Итак, для первой части вопроса правильные пути, а не альтернативы:), чтобы закодировать мое намерение, было бы следующим:
if (!a) a = expr;
или
a = a ? a : expr;
они должны быть оптимизированы одинаково (я думаю), хотя лично я предпочел бы первый (потому что он имеет один тип a
).
Однако вторая часть вопроса остается. Аргументы, высказанные Йенсом и Эдмундом о двусмысленности в a ||= expr
, одинаково хорошо применимы к a = a || expr
. случай назначения можно просто рассматривать как нормальный:
- конвертировать
a
в boolean - если это правда, значение всего выражения становится равным логическому значению
a
- иначе оцениваем
expr
, преобразуем результат в boolean, присваиваемa
и возвращаем его
Вышеприведенные шаги кажутся одинаковыми как для назначения, так и для нормального случая.