为啥 C 和 C++ 关键字“#defined”或“typedefed”也是它们的大写版本?
Posted
技术标签:
【中文标题】为啥 C 和 C++ 关键字“#defined”或“typedefed”也是它们的大写版本?【英文标题】:Why are C and C++ keywords "#defined" or "typedefed" as their capital versions too?为什么 C 和 C++ 关键字“#defined”或“typedefed”也是它们的大写版本? 【发布时间】:2013-06-28 18:03:31 【问题描述】:抱歉标题令人困惑,但我想不出一个能清楚地描述我的问题的标题。在编写 C 或 C++ 程序时,通常可以将 char 与 CHAR 或 int 与 INT 或 void 与 VOID 等关键字联系起来。
在winnt.h中,它们的定义如下:
#ifndef VOID
#define VOID void
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
#if !defined(MIDL_PASS)
typedef int INT;
#endif
#endif
这样做有什么用?是满足约定还是保证兼容性?
【问题讨论】:
这叫Windows怪异。 哈哈好的。因为有时函数被声明为返回 VOID 有时是 void,所以我认为这是某种约定 Why is everything in the Windows API typedef'd? 的可能重复项 - 在此处查看已接受的答案... "在编写 C 或 C++ 程序时,您通常可以 (...)" 否。仅在 Windows 上且仅当您包含(直接或间接)winnt.h
。无论如何,我认为没有理由在“现代”程序中这样做。
【参考方案1】:
我一直认为这些微不足道的 typedef(例如 int -> INT)比什么都更注重一致性。
我的意思是,Win32 中有许多大写的 typedef - DWORD、WORD、LPARAM、WPARAM、HANDLE、HWND,其中一些只是整数,它们的名称提供了它们使用的上下文,以及其中一些(例如 RECT 和 WNDCLASS)代表结构。
考虑函数 void f(int, BOOL, char, PAINTSTRUCT); 的情况对我来说,允许所有大写字母更加一致:VOID f(INT, BOOL, CHAR, PAINTSTRUCT)。但这可能就是我。
【讨论】:
【参考方案2】:大写 (#defined) 版本通常用于使代码与各种编译器兼容。并且 typedef 通常用于确保新命名的类型满足比编译器定义的原始类型更严格的规则。
通常,typedef int INT
或类似名称可以在检测编译器环境的块中看到,因此“INT”之类的名称可用于提供比“int”更具限制性的语义。
在“C”中,所有原始类型,如int
和char
,“至少”具有一定的大小(我现在不知道那个大小)。这意味着允许编译器使它们更大。我知道一个使用 32 位 char 类型的系统。这导致在做出假设时很容易编写不可移植的代码,例如假设“int”始终为 32 位。
在您的环境中进行实验可能会有所帮助。尝试如下的小程序,然后使用 32 位设置和 64 位设置编译并运行它:
int main (int argc, char **argv)
printf("sizeof INT=%u\n", sizeof (INT));
printf("sizeof int=%u\n", sizeof (int));
就 VOID 而言,将其定义为“void”有点奇怪。然而,它看起来像 - 在给定的 sn-p 中 - 它被用来确定其他是否已经由相同的头文件定义 - 这是“C”中非常重要的一步,因为重复的 typedef 会导致错误。 IIRC,重复定义可能导致错误或警告,具体取决于编译器和设置。
【讨论】:
如果INT
与int
的类型相同,那么除了与其他全大写类型名称保持一致外,它没有用处。如果INT
可以是int
以外的其他名称,那么这会非常令人困惑,并且应该选择不同的名称(可能是WORD
)。
这背后的原因实际上可以追溯到 16 位 / 32 位 API 之间的转换,其中内置的 int
曾经是一个 16 位字,他们试图使 INT为 32 位形式(MFC 1.1 到 MFC 2.0)
@KeithThompson: WORD
实际上命名了一个 16 位无符号类型,例如std::uint16_t
或 unsigned short
。还有DWORD
,它是32位但无符号的。
@MSalters:我认为WORD
和DWORD
是微软特有的。我可以想象有人将 WORD
定义为 32 位无符号类型——尽管考虑到与 Microsoft 特定定义的冲突,这可能不是一个好主意。【参考方案3】:
如果我没记错的话,主要是约定俗成的。我认为windows将其中一些放在其中以确保对某些数据类型的兼容性(例如整数,保持8位、16位、32位等的兼容性)。
【讨论】:
以上是关于为啥 C 和 C++ 关键字“#defined”或“typedefed”也是它们的大写版本?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 c++ 入门书使用 struct 关键字来描述类? [复制]
为啥 extern-only 和 defined-only 选项的 nm 工具输出重叠?