Чтобы ответить на этот вопрос, я считаю, что есть некоторые другие вопросы, на которые также необходимо ответить.
Почему в языке C есть оператор ?:
и почему он лучше, чем if-else
?
Насколько мне известно, никто не смог ответить на этот вопрос, не высказав лишь своего субъективного мнения. K&R 2.11 утверждает, что
«Условное выражение часто приводит к краткому коду».
а затем они иллюстрируют это строкой
printf("%6d%c", a[i], (i%10==9 || i==n-1) ? '\n' : ' ');
что является их собственным субъективным, мутным мнением. Лично я считаю, что
printf("%6d", a[i]);
if(i%10==9 || i==n-1)
printf("\n");
else
printf(" ");
намного, намного понятнее, поскольку я могу прочитать и понять этот код за 10 секунд, а не за 1 минуту, чтобы прочитать и понять версию K&R. Кроме того, мой код отделяет целочисленную печать от несвязанного форматирования. Но, конечно, это мое субъективное мнение, тут нет очевидных правильных или неправильных решений.
Что касается официальных источников, в обосновании C99 версии 5.10, 6.5.15 также не упоминается, зачем нужен оператор ?:. В основном просто говорится, что поведение оператора было изменено в новом стандарте:
Синтаксические ограничения на средний операнд условного оператора были ослаблены, чтобы включить больше, чем просто логическое ИЛИ-выражение: несколько существующих реализаций приняли эту практику.
Тип выражения условного оператора может быть void, структурой или объединением; большинство других операторов не работают с такими типами. Однако правила балансировки типа между указателем и целым числом были ужесточены, поскольку теперь только константа 0 может переносимо быть приведена к указателю.
Поэтому, если у кого-то возникнет желание выполнить арифметические действия над типами структур или объединений, ?: предположительно более удобен, чем if-else. Я не вижу в этом явной пользы, но это хоть какая-то причина для существования оператора.
Тогда следующим вопросом будет:
Почему в компиляторе GCC существует расширение компилятора для операнда ?:
?
Ответ на этот вопрос упоминается здесь:
Когда это становится полезным, когда первый операнд содержит или может (если это аргумент макроса) содержать побочный эффект. Тогда повторение операнда в середине вызовет побочный эффект дважды. При пропуске среднего операнда используется уже вычисленное значение без нежелательных последствий его повторного вычисления.
Таким образом, это расширение GCC не имеет ничего общего с удобочитаемостью или согласованностью языка, оно было просто добавлено, чтобы избежать нежелательных побочных эффектов.
Затем, чтобы попытаться ответить на исходный вопрос:
Почему тернарное расширение GCC не поддерживает присваивание?
Вероятно, потому, что доступ к lvalue в условии присваивания обычно не приводит к каким-либо нежелательным побочным эффектам. x = x ? : 2;
будет иметь нежелательные побочные эффекты только в том случае, если x будет объявлен как volatile
- чтение изменчивой переменной является побочным эффектом. Таким образом, единственное практическое применение, которое я вижу в x ?:= 2;
, состоит в том, чтобы предотвратить двойное обращение к одной и той же изменчивой переменной в одном и том же условном выражении.
И это свойство очень узкого и ограниченного значения. Возможно, это было бы полезно в каком-то специальном случае встроенной системы, когда вы читаете аппаратные регистры в требовательной системе реального времени ... кроме этого, я не вижу для этого никакого применения.
Я также не могу найти никаких официальных или канонических источников, указывающих на какое-либо использование самого оператора ?:, кроме традиции и субъективных предпочтений стиля кодирования.
person
Lundin
schedule
04.06.2013
x ?:= 2;
, но, возможно,x ?= ValueWhenXTrue:ValueWhenXFalse;
. - person chux - Reinstate Monica   schedule 04.06.2013if x is zero, set it to 2
. - person Richard J. Ross III   schedule 04.06.2013x ?:= 2
? В выражении:a = x ? b : c
четыре операнда, в расширенииa = x ?: b
три, в вашем предложенииa ?:= b
всего два - значение присваиваемое и значение подлежащее присвоению, а условного нет - вы сделали его бессмысленным - там не имеет разумной семантической интерпретации. - person Clifford   schedule 04.06.2013int x = some_var ?: 10;
крут, решит любую программную проблему или сделает код менее запутанным. - person Lundin   schedule 04.06.2013?:=
. Давайте присоединимся к WG14 и предложим изменение Стандарта (возможно, оно попадет в следующий Стандарт). - person pmg   schedule 04.06.2013