2015-02-18 3 views
2

Я читал comp.lang.c Описание booleans values, pre-C99. Он упоминает, что некоторые люди предпочитают определять свои собственные логические значения, как:Nitpicking booleans in C

#define TRUE (1==1) 
#define FALSE (!TRUE) 

Однако стандарт определяет оператор равенства всегда возвращает подписанный Int со значением 1, если два значения считаются равными (C11 - 6,5. 9), а логический оператор не должен возвращать значение int со значением 0, если значение сравнивается не равным 0 (C11 - 6.5.3.3).

Если это так, и приведенные выше определения использовать литералы, не оценка произойдет во время компиляции и в результате определения быть:

#define TRUE (1) 
#define FALSE (0) 

И последующий вопрос. Есть ли случай, когда имеет смысл определять истинные и ложные метки для чего-либо, кроме 1 и 0, соответственно?

Прошу простить, что я ссылаюсь на C11, когда мой вопрос касается C89, но у меня есть только стандарт C11.

+0

'TRUE = 1' и' FALSE = 0' привязаны к стандарту, как вы уже отметили. 'TRUE = (1 == 1)' и 'FALSE = (! TRUE)' привязаны к реализации, специфичной для компилятора. Поэтому, если вы получаете нестандартный компилятор (что плохо), вы все равно можете иметь несколько портативный код. –

+2

Обратите внимание, что '1 == 1' ** является **' 1' и '! (1 == 1)' ** ** ** - поскольку они являются * постоянными выражениями *. Один случай, когда это имеет смысл, - e. г. когда вы хотите, чтобы ваш компилятор не принимал 'FALSE' как литерал нулевого указателя. –

+2

Это также полезно, если сделано в файле заголовка, который может быть включен программой C++. Тогда 'TRUE' будет правильным' bool', набранным 'true'. – rodrigo

ответ

3

(1==1) и (!TRUE) являются полезными определениями некоторых компиляторов (у меня нет конкретного примера от верхней части головы), которые отслеживают, было ли целое число из логического сравнения. Это дает им возможность предупредить за

if (i) 

в то же время не предупредив для

if (i != 0) 

, а также не предупреждение для

j = i != 0; 
if (j) 

, хотя во всех трех случаях, условная является непостоянный int.

Таким образом, никакое предупреждение для int b = TRUE; ... if (b), поскольку b будет считаться истинным целым.

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

В то же время такие определения безвредны для других компиляторов, которые не отслеживают это, поскольку они просто видят постоянные выражения, которые оцениваются как 1 и 0.

 Смежные вопросы

  • Нет связанных вопросов^_^