Ошибка: lvalue требуется в этом простом C-коде? (Тернар с назначением?)

У меня есть:

#include<stdio.h>

int main()
{
 int a=5,b=6;
 (a>b)?b=a:b=b;    // Here is the error
 return 0;
}

Но если я заменю:

(a>b)?b=a:b=b;       // Error
with   
(a>b)?(b=a):(b=b);   // No-Error

Я понимаю, что lvalue - это значение, для которого что-то можно назначить, и как оно отличается от rvalue, но почему значение extra parenthesis делает разницу.

Ответ 1

Назначение имеет более низкий приоритет, чем тернарный оператор, поэтому строка оценивается как:

((a>b)?b=a:b)=b;

использование:

b=(a>b)?a:b;

Ответ 2

Собственно, в C этот код

(a>b)?b=a:b=b; 

анализируется многими компиляторами как

((a>b)?b=a:b)=b;

что является ошибкой, так как выражение ((a>b)?b=a:b) оценивает значение r, которое вы пытаетесь назначить с помощью b, что приводит к ошибке. Попытка присвоить rvalue является ошибкой. Если он не разбирается таким образом, то это просто синтаксическая ошибка. Но компилятору C НЕ разрешается анализировать его как:

((a>b)?b=a:(b=b)); //not allowed to parse by C language

Поскольку грамматика C не позволяет компилятору анализировать код, как указано выше.

Но то, что вы написали (исходный код) правильно, как С++.

Здесь грамматики C и С++ сильно различаются. И из-за этой разницы вы видите, что оба языка относятся к выражению по-разному. То есть the conditional expression in C++ отличается от the conditional expression in C.

Wikipedia имеет очень хорошее и правильное объяснение для этого:

Связывание операторов в C и С++ (в соответствующем Стандарты) на факторизованном языке грамматики, а не приоритета Таблица. Это создает некоторые тонкие конфликты. Например, в C, синтаксис условного выражения является:

логическое-OR-выражение? выражение: условное выражение

а в С++ -

логическое-OR-выражение? выражение: Назначение выражение

Следовательно, выражение:

e = a < d? a ++: a = d

анализируется по-разному в двух языки. В C это выражение является синтаксическая ошибка, но многие компиляторы разбора это как:

e = ((a < d? a ++: a) = d)

что является семантической ошибкой, поскольку результат условного выражения (который может быть ++) не является значением lvalue. В С++ он анализируется как:

e = (a < d? a ++: (a = d))

который является допустимым выражением.

Ответ 3

Это действительно:

((a>b)?b=a:b)=b; 

Примечание: вам просто нужно

b = (a>b)?a:b;

Ответ 4

Когда мы помещаем уравнение в скобки, оно рассматривается как выражение. И он возвращает некоторое значение, которое обеспечивает решение ошибки.