Применение приращения к троичному оператору в C - PullRequest
4 голосов
/ 26 июля 2011

Я думал, что троичный оператор возвращает либо значение слева, либо справа от : в зависимости от условия. Почему следующий фрагмент кода печатает 1?

#include <stdio.h>

int main(int argc, char const *argv[]) {
  int c = 0;
  (c?c:0)++;
  printf("%i", c);
  return 0;
}

Ответы [ 3 ]

13 голосов
/ 26 июля 2011

Может показаться, что у вас ошибка компилятора или, возможно, расширение языка, поскольку это недопустимо C. Вам нужно lvalue для применения оператора ++, а (c?c:0) не является lvalue.

0 голосов
/ 03 мая 2012

Я тоже наткнулся на некоторую странность, связанную с этим тоже.Кажется, что результат троичного условия может быть обработан как lvalue в gcc 3.3.2, но не в gcc 4.6 (у меня нет больше готовых версий для его дальнейшего сужения).На самом деле невозможно скомпилировать gcc 3.3.2 с использованием gcc 4.6 именно потому, что gcc 4.6 гораздо требовательнее относится к тому, что составляет lvalue.

Другой пример из источника gcc 3.3.2, который не компилируется с gcc 4.6:

char *x = ...;
*((void**)x)++ = ...;

gcc 4.6 может обрабатывать результат приведения как lvalue и увеличивать его, но gcc 4.6 не будет.

У меня также нет соответствующих стандартов для передачивыясните, что это что-то, что изменилось в официальном стандарте, или что-то, что gcc разрешило на каком-то этапе.

Обратите также внимание, что C ++ позволяет троичному оператору возвращать lvalue, хотя вы все еще не можете увеличить 0.Так что это действительный C ++, но не действительный C:

int c = 0, d = 0;
(c?c:d)++;
0 голосов
/ 26 июля 2011

Просто потому, что вы делаете

(c?c:0)++;

Если вы не позволите «++» произойти, вы получите то, что хотите.

#include <stdio.h>

int main(int argc, char const *argv[]) {
  int c = 0;
  /*  (c?c:0)++;  */
  printf("%i \n", (c?c:0)++ );
  return 0;
}

вывод:

$ gcc -o ternary ternary.c 
$ ./ternary 
0 

gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...