其他注意事项
移植代码时,请考虑以下几点:
以下假设不再有效:
#ifdef _WIN32 // Win32 code ... #else // Win16 code ... #endif
但是,64 位编译器定义_WIN32以实现向后兼容性。
以下假设不再有效:
#ifdef _WIN16 // Win16 code ... #else // Win32 code ... #endif
在这种情况下,else 子句可以表示_WIN32或_WIN64。
注意数据类型对齐。 TYPE_ALIGNMENT宏返回数据类型的对齐要求。 例如:
TYPE_ALIGNMENT( KFLOATING_SAVE )
x86 上的 == 4,Intel Itanium 处理器TYPE_ALIGNMENT( UCHAR )
上的 8 == 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;
结果出人意料地很大。 规则是,如果任一操作数是无符号的,则结果为无符号。 在前面的示例中,将 转换为无符号值,除以 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 打印多态数据。 Visual C++ 还支持 %I64 打印 64 位的值。