移植代码时,请考虑以下几点:
以下假设不再有效:
#ifdef _WIN32 // Win32 code ... #else // Win16 code ... #endif
但是,64 位编译器定义_WIN32以实现向后兼容性。
以下假设不再有效:
#ifdef _WIN16 // Win16 code ... #else // Win32 code ... #endif
在这种情况下,else 子句可以表示_WIN32或_WIN64。
请谨慎使用数据类型对齐方式。 TYPE_ALIGNMENT 宏返回数据类型的对齐要求。 例如:在 x86 上
TYPE_ALIGNMENT( KFLOATING_SAVE )
== 4,Intel Itanium 处理器上的 8TYPE_ALIGNMENT( UCHAR )
== 1例如,当前如下所示的内核代码:
ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );
应可能更改为:
ProbeForRead( UserBuffer, UserBufferLength, TYPE_ALIGNMENT(IOCTL_STRUC) );
为 Intel Itanium 系统禁用内核模式对齐异常的自动修复。
注意 NOT作。 请考虑以下事项:
UINT_PTR a; ULONG b; a = a & ~(b - 1);
问题是 ~(b–1)生成“0x0000 0000 xxxx xxxx”,而不是“0xFFFF FFFF xxxx xxxx”。 编译器不会检测到此情况。 若要解决此问题,请按如下所示更改代码:
a = a & ~((UINT_PTR)b - 1);
请小心执行未签名和已签名的作。 请考虑以下事项:
LONG a; ULONG b; LONG c; a = -10; b = 2; c = a / b;
结果意外很大。 规则是,如果任一作数未签名,则结果为 unsigned。 在前面的示例中,a 转换为无符号值,除以 b,结果存储在 c 中。 转换不涉及数字作。
作为另一个示例,请考虑以下事项:
ULONG x; LONG y; LONG *pVar1; LONG *pVar2; pVar2 = pVar1 + y * (x - 1);
出现此问题的原因是 x 是未签名的,这使得整个表达式未签名。 除非 y 为负,否则此作正常。 在这种情况下,y 转换为无符号值,将使用 32 位精度、缩放和添加到 pVar1 来计算表达式。 32 位无符号负数将成为较大的 64 位正数,从而得出错误的结果。 若要解决此问题,请将 x 声明为有符号值或显式类型化,以在表达式中 LONG。
在进行碎片大小分配时请小心。 例如:
struct xx { DWORD NumberOfPointers; PVOID Pointers[100]; };
以下代码错误,因为编译器将用额外的 4 个字节填充结构,使 8 字节对齐:
malloc(sizeof(DWORD) + 100*sizeof(PVOID));
以下代码正确:
malloc(offsetof(struct xx, Pointers) + 100*sizeof(PVOID));
不要将
(HANDLE)0xFFFFFFFF
传递给 CreateFileMapping等函数。 请改用 INVALID_HANDLE_VALUE。打印字符串时,请使用正确的格式说明符。 使用 %p 以十六进制形式打印指针。 这是打印指针的最佳选择。 Microsoft Visual C++支持打印多态数据的 %I。 视觉C++还支持 %I64 来打印 64 位的值。