将 32 位驱动程序源代码转换为使用 新数据类型后,可以使用 64 位编译器来识别最初遗漏的任何与类型相关的问题。 首次为 64 位 Windows 编译此代码时,编译器可能会生成许多指针截断或类型不匹配警告。 使用这些警告作为指导,使代码更可靠。 最好消除所有警告,尤其是指针截断警告。
下面是此类警告的示例:
warning C4311: 'type cast' : pointer truncation from 'unsigned char *' to 'unsigned long '
例如,以下代码可以生成 C4311 警告:
buffer = (PUCHAR)srbControl;
(ULONG)buffer += srbControl->HeaderLength;
若要更正代码,请进行以下更改:
buffer = (PUCHAR)srbControl;
(ULONG_PTR)buffer += srbControl->HeaderLength;
预定义宏
编译器定义以下宏来标识平台。
宏 | 含义 |
---|---|
_WIN64 |
64 位平台。 |
_WIN32 |
32 位平台。 此值也由 64 位编译器定义,以实现向后兼容性。 |
_WIN16 |
16 位平台。 |
以下宏特定于体系结构。
宏 | 含义 |
---|---|
_M_IA64 |
64 位 Intel 平台。 |
_M_IX86 |
32 位 Intel 平台。 |
请勿使用这些宏,除非与特定于体系结构的代码一起使用。 请尽可能使用_WIN64、_WIN32和_WIN16。
64 位编译器开关和警告
有一个警告选项可帮助移植到 64 位 Windows。 -Wp64-W3 开关启用以下警告:
C4305:截断警告。 例如,“return”:从“unsigned int64”到“long”的截断。
C4311:截断警告。 例如,“type cast”:从“int*_ptr64”到“int”的指针截断。
C4312:转换为较大大小的警告。 例如,“type cast”:从“int”转换为“int*_ptr64”,其大小更大。
C4318:传递零长度。 例如,将常量零作为长度传递给 memset 函数。
C4319:Not 运算符。 例如,“~”:将“unsigned long”扩展到更大的“unsigned _int64”的零。
C4313:调用具有冲突的转换类型说明符和参数的 printf 函数系列。 例如,格式字符串中的“printf”: “%p”与类型为“_int64”的参数 2 冲突。另一个示例是调用 printf (“%x”,pointer_value) ;这会导致截断上限 32 位。 正确的调用是 printf (“%p”,pointer_value) 。
C4244:与现有警告 C4242 相同。 例如,“return”:从“_int64”转换为“unsigned int”,可能会丢失数据。