https://blog.csdn.net/ababab12345/article/details/103408685
linux DWORD的正确定义
在进行C语言程序移植时,有时候要把Windows下的程序移植到Linux下,在Windows平台上通常是用VC++开发,在Linux上通常使用GCC编译代码。在Windows平台上,大家一般用VC来编译代码,VC天然的整合了Windows SDK,在VC里有一个数据类型DWORD,它其实不是一个C语言内建的类型,它是由typedef 创建的类型,最早的定义是在Windows SDK定义的,微软将它定义在windef.h文件里,定义如下:
typedef unsigned long DWORD;
DWORD 的本意是定义一个双字类型(double word),在计算机里一个字节(BYTE)是8位,一个字是16位,双字是32位。微软的VC的long 在16位CPU,32位CPU与64位CPU里的长度一直为32位,因此在VC里DWORD一直可以用 无符号 long(即 unsigned long)类型来表示双字。在Linux系统里,大家用的编译器是GCC,long类型的长度是不定的,在32位操作系统里,sizeof(long)=4,在64位操作系统里,sizeof(long)=8,因此,在GCC里再用unsigned long来定义DWORD,则在x64系统里,应该是不正确的。
GCC编译器基本数据类型长度对照表
数据类型 GCC 32位 GCC 64位
sizeof(char) 1 1
sizeof(double) 8 8
sizeof(float) 4 4
sizeof(int) 4 4
sizeof(short) 2 2
sizeof(long) 4 8
sizeof(long long) 8 8
sizeof(long double) 12 16
sizeof(complex long double) 16 32
而Linux里的GCC编译器整数类型 int 的长度无论是在32位CPU还是64位CPU上,长度都是4,因此,为了移植代码尽量符合Microsoft的初衷,在Linux相关C/C++代码里应该如下定义DWORD类型:
typedef unsigned int DWORD;
虽然在GCC里将DWORD定义为long,在大多数情况下,程序能够正常运行,但也许在一些需要数据交互的情况下,程序就不一定能够正常了,例如将DWORD记录在文件里,如果在64位操作系统里 将被存储64位数据,在32位操作系统里,将被存储32位数据,因此可能会出现错误。
在以前的32位程序设计当中,好多代码一直把DWORD 与指针类型互用,例如CreateIoCompletionPort等函数,在64位移植时可能会发送错误。