【问题标题】:BYTE, WORD and DWORD macros definitionBYTE、WORD 和 DWORD 宏定义
【发布时间】:2017-12-07 15:02:39
【问题描述】:

我试图了解,定义 BYTEWORDDWORD 宏的最佳方法是什么,这在 question 的答案中有所提及。

#define LOWORD(l) ((WORD)(l))
#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))
#define LOBYTE(w) ((BYTE)(w))
#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))

假设是否正确:

  • BYTE 被宏定义为 #define BYTE __uint8_t
  • WORD 被宏定义为 #define WORD __uint16_t
  • DWORD 是宏定义为 #define DWORD __uint32_t

如果是,为什么要转换为另一个宏而不是转换为 __uint8_t__uint16_t__uint32_t?这样写是为了提高清晰度吗?

我还找到了另一个question,其中的答案包括typedef,还有一点点研究我找到了question about comparing #define and typedef 的答案。在这种情况下使用typedef 会更好吗?

【问题讨论】:

  • 你可以为所欲为。它们是 Windows 上使用的名称。像__uint8_t 这样的名字完全是非标准的。他们是否做你想做的事是编译器的心血来潮。
  • 除了使用 __uint8_t、__uint16_t 或 __uint32_t,您还可以包含 stdint.h 并使用 uint8_t、uint16_t 或 uint32_t 其中conform the standard
  • 这些是来自 Windows SDK 的 typedef,它们将 winapi 与 C 编译器实现和处理器架构隔离开来。你的#defines 看起来不错。您发布的宏是简单的破解程序,用于从较大的整数类型中提取 8 位或 16 位值,SendMessage() 特别需要大量处理才能将消息参数放入它所采用的两个参数中。 30 年前,当他们不得不将 GUI 塞进 1/4 兆字节的内存中时,这种经济状况很重要。
  • @JonathanLeffler 但是在 GNU/Linux 环境中使用像 GNU GCC 这样的编译器怎么样?
  • GCC 怎么样?双下划线名称保留供实现用于任何目的。它们不受任何标准的强制。您所拥有的将适用于 GCC(以及 Clang,因为它模拟 GCC),但其他编译器不需要识别类型。

标签: c


【解决方案1】:

这是一个可移植的解决方案:

#include <stdint.h>

typedef uint32_t DWORD;   // DWORD = unsigned 32 bit value
typedef uint16_t WORD;    // WORD = unsigned 16 bit value
typedef uint8_t BYTE;     // BYTE = unsigned 8 bit value

【讨论】:

  • 对于 BOOL 应该是 "typedef int32_t BOOL;"
  • 那么 uint8_t 和 BYTE 一样吗?
  • @bluejayke 是的,应该是,但 nBYTE 不是标准类型。它仅适用于 Windows。
【解决方案2】:

您已将其定义在:https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx,并且已在 WinAPI 的 Windows 数据类型标头中定义:

typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef unsigned long DWORD;

它是一种类型,而不是宏。

【讨论】:

  • 这些 typedef 在其他编译器中不一定正确(例如,DWORD 假定为 32 位,但 unsigned long 在非 Microsoft 编译器上可能更大)。
猜你喜欢
  • 2018-01-12
  • 1970-01-01
  • 1970-01-01
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 2022-07-27
  • 1970-01-01
  • 2020-01-21
相关资源
最近更新 更多