6
// <windef.h>

typedef int                 BOOL;

由于 int 是 32 位,这不是浪费内存吗?

以防万一我错了,我尝试将法线发送bool*到需要的函数,BOOL*直到我使用 typedef int 才起作用。

4

5 回答 5

19

哇,那里慢一点。首先,我很确定int自从开始在 x86 上编程以来,程序员一直在使用 4 字节的布尔变量。(过去没有bool数据类型之类的东西)。我敢猜测 Windows 3.1 中也有同样的 typedef <Windows.h>

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

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

在你因为制作那个“浪费”的 typedef 而对 MS 大发雷霆之前。考虑一下:在底层,大多数编译器(可能)仍然将数据类型实现bool为 4 字节int,原因与我刚才提到的相同。在 gcc 中尝试,并查看映射文件。我打赌我是对的。

于 2012-06-20T23:30:32.527 回答
13

首先,系统 API 中使用的类型必须尽可能与语言无关,因为该 API 将被多种编程语言使用。出于这个原因,任何在某些语言中可能不存在或可能在其他语言中以不同方式实现的“概念”类型都是毫无疑问的。例如,bool适合该类别。最重要的是,在系统 API 中,将接口类型的数量保持在最低限度是一个非常好的主意。任何可以用 表示的东西都int应该用 表示int

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

于 2012-06-20T23:38:24.070 回答
3

历史上BOOL被用作anything-not-0 = TRUE 类型。例如,一个对话过程返回一个BOOL,它可以携带很多信息。下面的签名来自微软自己的文档

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

签名和函数结果混淆了几个问题,所以在现代 API 中它是

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

这种新奇的声明必须与旧的声明保持兼容。这意味着INT_PTR并且BOOL必须是相同的大小。这意味着在 32 位编程中,BOOL是 32 位。

通常,由于BOOL可以是任何值,而不仅仅是 0 和 1,因此将 a 与 进行比较是一个非常不好的BOOL主意TRUE。即使将其与 进行比较FALSE,这通常也是不好的做法,因为它很容易给人一种印象,即进行比较TRUE是可以的。另外,因为它完全没有必要。

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

这就是为什么直接与逻辑 FALSE 或 TRUE 比较不是一个好主意的另一个原因。

于 2013-01-21T13:35:20.893 回答
2

处理器是 32 位的,当它在零整数上运行时有一个特殊的标志,使得对 32 位布尔值的测试非常、非常、非常快。

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

如果您担心内存空间,那么您可能会担心 4 字节布尔变量。

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

如果这让您感到困扰,您也许可以让您的编译器优化内存使用。

于 2012-06-20T23:35:25.747 回答
0

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

这个问题的答案绝对只是“遗留原因”。也就是“不要碰没坏的东西”。更改一行代码(例如进行次要优化)可能会引入数百个没人愿意处理的其他问题。

于 2019-01-10T07:38:17.783 回答