在C语言中挑剔布尔人

在C语言中挑剔布尔人,c,language-lawyer,c89,C,Language Lawyer,C89,我正在读C99之前的书中对布尔值的描述。它提到有些人更喜欢将自己的布尔值定义为: #define TRUE (1==1) #define FALSE (!TRUE) 但是,该标准规定,当两个值比较相等(C11-6.5.9)时,相等运算符始终返回值为1的带符号整数,如果值比较不等于0(C11-6.5.3.3),则逻辑not运算符应返回值为0的整数 如果是这种情况,并且上述定义使用文本,那么计算不会在编译时进行,并且生成的定义是: #define TRUE (1) #define FALSE (0

我正在读C99之前的书中对布尔值的描述。它提到有些人更喜欢将自己的布尔值定义为:

#define TRUE (1==1)
#define FALSE (!TRUE)
但是,该标准规定,当两个值比较相等(C11-6.5.9)时,相等运算符始终返回值为1的带符号整数,如果值比较不等于0(C11-6.5.3.3),则逻辑not运算符应返回值为0的整数

如果是这种情况,并且上述定义使用文本,那么计算不会在编译时进行,并且生成的定义是:

#define TRUE (1)
#define FALSE (0)
还有一个后续问题。在任何情况下,将真标签和假标签分别定义为除1和0以外的任何值都有意义吗

请原谅,当我的问题涉及C89时,我引用了C11,但我手头只有C11标准。

(1==1)
(!TRUE)
在一些编译器上是有用的定义,它们跟踪整数是否来自布尔比较。这使他们能够发出警告

if (i)
但同时不警告

if (i != 0)
j = i != 0;
if (j)
也不是警告,

if (i != 0)
j = i != 0;
if (j)
即使在这三种情况下,条件都是一个非常量
int

这样,不会为
int b=TRUE生成警告
..
如果(b)
,因为
b
将被视为真值整数

你可以提出这样的警告是无用的合理论点,但其他人也可以提出这样的警告确实有用的合理论点。它在普通代码中会有许多误报,但如果以避免此类警告的方式编写,可能会使代码更可读


同时,这样的定义对其他不跟踪它的编译器是无害的,因为它们只看到计算结果为
1
0
的常量表达式,正如您所指出的那样
TRUE=1
FALSE=0
都绑定到标准
TRUE=(1==1)
FALSE=(!TRUE)
绑定到特定于编译器的实现。因此,如果您使用的是不符合标准的编译器(这很糟糕),您仍然可以使用一些可移植的代码。请注意,
1==1
1
!(1==1)
为零–因为它们是常量表达式。一个有意义的例子是e。G当您希望编译器不接受<代码> false >代码>作为空指针文本时,如果在一个包含C++程序的头文件中完成,也是有用的。然后
TRUE
将是正确的
bool
类型
TRUE
。相关(与相关讨论):@TheParamagneticCroissant:
!(1==1)
是有效的空指针常量。(例如,
(0,0)
(0,!(1==1))
等不是,如果在指针上下文中使用,编译器会抱怨。)