64 位编译器

将 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”,可能会丢失数据。