其他考量

移植程式碼時,請考慮下列幾點:

  • 下列假設已不再有效:

    #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)0xFFFFFFFFCreateFileMapping之類的函式。 請改用 INVALID_HANDLE_VALUE

  • 列印字串時,請使用適當的格式規範。 使用 %p 以十六進位列印指標。 這是列印指標的最佳選擇。 Microsoft Visual C++支援 %I 列印多型資料。 Visual C++ 也支援 %I64 來列印 64 位的值。