其他考量
移植程式碼時,請考慮下列幾點:
下列假設已不再有效:
#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 位的值。