Любой компилятор C, где «==» оценивается больше одного?

Поскольку любое ненулевое значение означает true, но операторы > , < , == и т. Д., Возвращающие 1 для true, мне любопытно, есть ли какие-либо известные компиляторы C, где эти операторы могут привести к значению, превышающему 1 .

Другими словами, существует ли какой-либо компилятор, где int i = (a==b) ; приведет к неопределенному поведению, если я намерен использовать i не как логическое значение, а как целое число, и предположил бы, что это будет либо 0 либо 1 ?

Нет, если они есть, они не являются компиляторами C 🙂 Стандарт требует, чтобы операторы relational и равенства возвращали 1 для true и 0 для false.


Правило для интерпретации интегральных значений в виде логических значений по C означает, что 0 является ложным, а любое другое значение истинно. См. Разделы C11, посвященные if/while/do/for , которые содержат язык типа "while the expression compares unequal to zero" . В частности:

6.8.4.1/2: In both forms [of the if statement, one with and one without an else clause], the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal to 0.

6.8.5/4: An iteration statement [while, do and for] causes a statement called the loop body to be executed repeatedly until the controlling expression compares equal to 0.


Однако совершенно ясно, какой результат вы получите для выражений типа сравнения, вы либо получите 0 либо 1 . Соответствующие биты стандарта C11 для них все под 6.5 Expressions :

6.5.8/6: Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.

6.5.9/3: The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence. Each of the operators yields 1 if the specified relation is true and 0 if it is false.

6.5.13/3: The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0.

6.5.14/3: The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0.

6.5.3.3/5: The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0.


И это поведение возвращается к C99 и C89 (дни ANSI). Секции C99, относящиеся к операторам реляционной и равенства, также указывают, что возвращаемые значения равны 0 или 1.

И, хотя проект C89 явно не диктует возвращаемые значения для операторов равенства, он говорит:

Операторы == (равные) и a = = (не равные) аналогичны операторам реляций, за исключением их более низкого приоритета.

И в разделе реляционных операторов говорится:

Каждый из операторов <(меньше),> (больше), <= (меньше или равен) и> = (больше или равен) должен давать 1, если указанное отношение истинно и 0, если оно ложный.

Ссылка: http://flash-gordon.me.uk/ansi.c.txt, так как у меня нет никаких копий стандартов C89, плавающих вокруг. У меня есть второе издание K & R (ANSI one from 1988), которое в основном говорит то же самое, в разделах A7.9 и A7.10 Приложения A, Справочное руководство. Если вы хотите получить окончательный ответ от первого издания, это должно произойти от кого-то с женой, которая менее подвержена выбросу старого мусора.


Приложение:

По словам Майкла Барра, который либо не женат, либо имеет более любезную жену, чем я, с точки зрения хранения старых книг 🙂

K & R 1st Edition (1978) также говорит то же самое в 7.6 и 7.7: «[реляционные операторы] все дают 0, если указанное отношение ложно и 1, если оно истинно». … «Операторы [равенства] в точности аналогичны реляционным операторам, за исключением их более низкого приоритета».

Они гарантированно вернут 0 или 1 .

Ссылка:
C99 Стандарт: 6.5.9 Операторы равенства

Пункт 3:

Операторы == (равно) и! = (Не равны) аналогичны операциям реляционной связи, за исключением их более низкого приоритета.108) Каждый из операторов дает 1, если указанное отношение истинно и 0, если оно ложно. Результат имеет тип int. Для любой пары операндов истинно одно из отношений.

Я не думаю, что люди здесь отвечают на этот вопрос. Вопрос не в том, что говорится в стандарте, вопрос в том, есть ли там какие-либо примечательные компиляторы, которые не подчиняются стандарту в этом отношении.

Нет, насколько я знаю, нет.

У меня нет доступа к стандарту C, но, согласно Википедии,

C использует целочисленный тип, где реляционные выражения, такие как i> j, и логические выражения, связанные && и || имеют значение 1, если true и 0, если false, тогда как тестовые части if, while, for и т. д. обрабатывают любое ненулевое значение как истинное.

Википедия, к счастью, имеет правильные цитаты, но поскольку они являются ссылками на книги, не уверен, какая помощь будет :).

Насколько я могу найти, это от 6.5.9 пункта 3 в стандарте C99

Операторы == (равно) и! = (Не равны) аналогичны операциям реляционной связи, за исключением их более низкого приоритета.108) Каждый из операторов дает 1, если указанное отношение истинно и 0, если оно ложно. Результат имеет тип int. Для любой пары операндов истинно одно из отношений.

Поэтому кажется, что оцененные значения должны быть либо 1, либо 0

По спецификации, чтобы считаться языком C, условные операторы должны возвращать 0 для false и 1 для true.

В форме хайку:

 Specification Disallows this behavior, Otherwise not C. 

До c89 / c90 / ANSI-C операторы сравнения гарантировали получение нулевого значения в «ложном» состоянии и в противном случае не равным нулю. Заменитель 1 для истинной «стандартизации», введенный c89, редко необходим, и в тех случаях, когда это необходимо, можно использовать a = (b==c) ? 1 : 0; a = (b==c) ? 1 : 0; ,