为什么WinAPI对BOOL类型使用int(32位)?

时间:2012-06-20 23:27:26

标签: c++ windows winapi boolean int

// <windef.h>

typedef int                 BOOL;

这不是浪费内存,因为int是32位吗?

万一我错了,我尝试将一个普通的bool*发送到一个需要BOOL*的函数,直到我使用了typedef int才行。

5 个答案:

答案 0 :(得分:19)

哇,在那里放慢一点。首先,我非常确定自x86编程开始以来,程序员一直在使用4字节int作为布尔变量。 (过去没有bool数据类型这样的东西。我冒昧地猜测这个相同的typedef在Windows 3.1 <Windows.h>中。

其次,您需要了解有关架构的更多信息。您有一台32位机器,这意味着所有CPU寄存器都是4字节或32位宽。因此,对于大多数内存访问,存储和访问4字节值比<1>字节值更高效

如果有四个1字节的布尔变量打包到一个4字节的内存块中,其中三个不是DWORD(4字节)对齐的。这意味着CPU /内存控制器实际上必须更多工作才能获得值。

在你为了制造那种“浪费”的typedef而粉碎MS之前。考虑一下:由于我刚刚提到的相同原因,大多数编译器(可能)仍然bool数据类型实现为4字节int。在gcc中尝试一下,看看地图文件。我打赌我是对的。

答案 1 :(得分:13)

首先,系统API中使用的类型必须尽可能与语言无关,因为该API将被多种编程语言使用。出于这个原因,任何可能在某些语言中不存在或者可能在其他语言中以不同方式实现的“概念”类型都是不可能的。例如,bool符合该类别。最重要的是,在系统API中,最好将接口类型的数量保持在最低水平。 int可以表示的任何内容都应由int表示。

其次,你断言这是“浪费记忆”毫无意义。为了成为“浪费内存”,人们必须构建一个涉及大量BOOL元素的聚合数据类型。 Windows API不使用此类数据类型。如果您在程序中构建了这种浪费的数据类型,那实际上就是您的错。同时,Windows API不会以任何方式强制您将您的布尔值存储在BOOL类型中。您可以为此目的使用字节和偶数位。换句话说,BOOL是纯粹的接口类型。 BOOL类型的对象通常不会占用任何长期记忆,如果你正确使用它。

答案 2 :(得分:2)

处理器是32位的,并且当它在零整数上运行时具有特殊标志,从而非常非常快速地测试32位布尔值。

测试1位或1字节的布尔值将慢很多倍。

如果你担心内存空间,那么你可能会担心4字节的bool变量。

然而,大多数程序员更担心性能,因此默认是使用更快的32位bool。

如果这困扰你,你或许可以让你的编译器优化内存使用。

答案 3 :(得分:2)

历史上BOOL被用作 nothing-not-0 = TRUE类型。例如,一个对话框程序返回BOOL,它可以携带大量信息。以下签名来自Microsoft's own documentation

BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) 

签名和功能结果混淆了几个问题,因此in the modern API取而代之的是

INT_PTR CALLBACK DialogProc(
    _In_  HWND hwndDlg,
    _In_  UINT uMsg,
    _In_  WPARAM wParam,
    _In_  LPARAM lParam
);

这个新奇的声明必须与旧声明保持一致。这意味着INT_PTRBOOL的大小必须相同。这意味着在32位编程中,BOOL是32位。

一般来说,由于BOOL可以是任何值,而不仅仅是0和1,因此将BOOLTRUE进行比较是一个非常糟糕的想法。虽然它可以将它与FALSE进行比较,但这通常也是不好的做法,因为它很容易让人觉得与TRUE进行比较就行了。此外,因为这是非常不必要的。

顺便说一下,Windows API中有更多的布尔类型,特别是VARIANT_BOOL,它是16位,其中逻辑TRUE表示为全1位模式,即-1作为有符号值...

这是为什么直接与逻辑FALSE或TRUE进行比较不是一个好主意。

答案 4 :(得分:0)

这里的大多数答案似乎都是错误的信息。为布尔值使用4个字节并不比使用1个字节快。 x86体系结构读取1字节的速度与读取4字节的速度一样快,但是1字节的内存更少。对性能的最大威胁之一是内存使用率。使用太多的内存,您将有更多的缓存未命中,并且您的程序将变慢。如果您只处理少量(数百个!)布尔值,那么这些东西并不重要,但是如果您有大量布尔值,那么使用更少的内存是提高性能的关键。在大型数组的情况下,我建议使用1位而不是1个字节,因为如果该位节省了87%的内存,则掩盖该位的额外逻辑是无关紧要的。您会发现带有标志位域的这种做法很多。

该问题的答案无疑是“传统原因”。也就是说,“不要碰那些没坏的东西。”更改代码行(例如进行次要的优化)可能会引入其他数百个没人想处理的问题。