在我正在研究的一些代码中,我遇到了对真相和虚假的奇怪的重新定义.我之前已经看过这样的事情,以便更加严格/确定地进行检查,但是这一点在我的脑海里有点奇怪,我想知道是否有人可以告诉我这些定义的原因是什么,请参阅下面我的评论旁边:
#define FALSE (1 != 1) // why not just define it as "false" or "0"?
#define TRUE (!FALSE) // why not just define it as "true" or "1"?
Run Code Online (Sandbox Code Playgroud)
这个代码库还有许多其他奇怪的怪异.就像所有标准类型的重新定义一样:
#define myUInt32 unsigned integer // why not just use uint32_t from stdint?
Run Code Online (Sandbox Code Playgroud)
所有这些小"怪癖"让我觉得我错过了一些明显的东西,但我真的看不出这一点:(
注意:严格来说这是c ++代码,但它可以从'c'项目移植.
Lig*_*ica 34
意图似乎是可移植性.
#define FALSE (1 != 1) // why not just define it as "false" or "0"?
#define TRUE (!FALSE) // why not just define it as "true" or "1"?
Run Code Online (Sandbox Code Playgroud)
它们在支持它的语言中具有布尔类型(C++),同时为那些不支持它的人提供仍然有用的数值(C - 甚至C99和C11,显然,尽管他们获得了显式的布尔数据类型).
在可能的情况下使用布尔值对于函数重载是有益的.
#define myUInt32 unsigned integer // why not just use uint32_t from stdint?
Run Code Online (Sandbox Code Playgroud)
如果stdint可以,这很好.你可以把这些事情视为理所当然,但这是一个广阔的世界!此代码识别出这一点.
免责声明:就个人而言,我会坚持标准,并简单地说,1990年以后发布的编译器是先决条件.但我们不知道该项目的基本要求是什么.
TRWTF是有问题的代码的作者并未在评论中解释这一点.
Naw*_*waz 11
#define FALSE (1 != 1) // why not just define it as "false" or "0"?
Run Code Online (Sandbox Code Playgroud)
我认为这是因为表达式的类型(1!=1)取决于语言对布尔值的支持 - 如果它是C++,则类型是bool,否则它是int.
另一方面0,总是int,在两种语言中,并且false在C中不被识别.
严格来说这是c ++代码,但它可以从'c'项目移植.
这是关于如前所述的可移植性,但它实际上远远超出了.它是语言定义的巧妙利用,以符合语言.
这些荒谬的看着宏并不像第一眼看上去是荒谬的,但它们实际上是巧妙的,因为他们保证C和C++中TRUE,并FALSE有正确的值(和类型)true和false(即使编译器是C编译器没有那些关键字,所以你不能轻易写出类似的东西#define TRUE true).
在C++代码中,由于语言定义,这样的构造将是无用的 true和false作为关键字.
但是,为了使C和C++在相同的代码库中无缝地互操作,您需要"适用于两者的东西"(除非您想使用不同的代码样式).
定义这些宏的方式是C++标准的证明,它明确地模糊了什么值true和false实际上有.C++标准规定:
bool类型的值为true或false.
[...]
零值,空指针值或空成员指针值转换为false; 任何其他值都转换为true.
[...]
bool类型的prvalue可以转换为int类型的prvalue,false变为零,true变为1.
注意它是如何表示存在两个特定值以及它们的名称是什么,以及它们转换为和从哪个相应的整数值,但它没有说明这些值是什么.你可能会倾向于认为,价值是明显0和1(和incidentially你可能已经猜对了),但事实并非如此.故意没有定义实际值.
这类似于如何定义指针(特别是空指针).请记住,零整数文字转换为空指针并且空指针转换为false,比较等于...等等等等等.
有很多关于哪些转换为什么和什么,但它没有说任何地方,一个空指针必须具有零二进制表示(事实上,存在着一些奇特的架构相比较,这是不是这样的!).
其中许多都有历史原因,例如从C迁移的旧代码,非标准C++编译器的代码,交叉编译器代码(可移植性),支持向后兼容性,遵循代码样式,坏习惯.
有些编译器没有<cstdint>像整数类型那样uint32_t,或者没有<cstdbool>.一个优秀的程序员必须定义所有内容并大量使用预处理器,以便在不同的编译器上很好地定义他的程序.
今天,我们就可以使用<cstdint>,true/false,<cstdbool>,...大家都开心!
| 归档时间: |
|
| 查看次数: |
6584 次 |
| 最近记录: |