Megosztás:


További szempontok

A kód portolása során vegye figyelembe a következő szempontokat:

  • A következő feltételezés már nem érvényes:

    #ifdef _WIN32 // Win32 code
        ...
    #else         // Win16 code
        ...
    #endif
    

    A 64 bites fordító azonban _WIN32 határoz meg a visszamenőleges kompatibilitás érdekében.

  • A következő feltételezés már nem érvényes:

    #ifdef _WIN16 // Win16 code
        ...
    #else         // Win32 code
        ...
    #endif
    

    Ebben az esetben a másik záradék _WIN32 vagy _WIN64 jelölhet.

  • Ügyeljen az adattípusok igazítására. A TYPE_ALIGNMENT makró egy adattípus igazítási követelményeit adja vissza. Például: TYPE_ALIGNMENT( KFLOATING_SAVE ) == 4 x86-on, 8 Intel Itanium processzoronTYPE_ALIGNMENT( UCHAR ) == 1 mindenhol

    Példaként a jelenleg így néz ki kernelkód:

    ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );
    

    valószínűleg a következőre kell módosítani:

    ProbeForRead( UserBuffer, UserBufferLength, TYPE_ALIGNMENT(IOCTL_STRUC) );
    

    A kernel módú igazítási kivételek automatikus javítása le van tiltva az Intel Itanium-rendszerek esetében.

  • Legyen óvatos a NOT műveletekkel. Vegye figyelembe a következőket:

    UINT_PTR a; 
    ULONG b;
    a = a & ~(b - 1);
    

    A probléma az, hogy a ~(b–1) "0x0000 0000 xxxx xxxx" értéket állít elő, és nem "0xFFFF FFFF xxxx xxxx". Ezt a fordító nem fogja észlelni. A probléma megoldásához módosítsa a kódot az alábbiak szerint:

    a = a & ~((UINT_PTR)b - 1);
    
  • Legyen óvatos az aláíratlan és aláírt műveletek végrehajtásával. Vegye figyelembe a következőket:

    LONG a;
    ULONG b;
    LONG c;
    
    a = -10;
    b = 2;
    c = a / b;
    

    Az eredmény váratlanul nagy. A szabály az, hogy ha bármelyik operandus nincs aláírva, az eredmény nem lesz aláírva. Az előző példában a rendszer egy előjel nélküli értékké alakítja át, b-vel osztva, és a c fájlban tárolt eredményt. Az átalakítás nem jár numerikus manipulációval.

    Egy másik példaként vegye figyelembe a következőket:

    ULONG x;
    LONG y;
    LONG *pVar1;
    LONG *pVar2;
    
    pVar2 = pVar1 + y * (x - 1);
    

    A probléma azért merül fel, mert az x nincs aláírva, ezért a teljes kifejezés nincs aláírva. Ez jól működik, kivéve, ha y negatív. Ebben az esetben az y érték nem aláírt értékké lesz konvertálva, a kifejezés kiértékelése 32 bites pontossággal történik, skálázva és hozzáadva a pVar1 értékhez. A 32 bites aláíratlan negatív szám nagy, 64 bites pozitív szám lesz, ami rossz eredményt ad. A probléma megoldásához deklarálja az x értéket aláírt értékként, vagy írja be explicit módon a kifejezésben LONG.

  • Legyen óvatos a darabméret-foglalások készítésekor. Például:

    struct xx {
       DWORD NumberOfPointers;
       PVOID Pointers[100];
    };
    

    A következő kód hibás, mert a fordító további 4 bájttal fogja kipárnázni a szerkezetet a 8 bájtos igazításhoz:

    malloc(sizeof(DWORD) + 100*sizeof(PVOID));
    

    A következő kód helyes:

    malloc(offsetof(struct xx, Pointers) + 100*sizeof(PVOID));
    
  • Ne adjon át (HANDLE)0xFFFFFFFF olyan függvények számára, mint CreateFileMapping. Ehelyett használja a INVALID_HANDLE_VALUE.

  • Sztring nyomtatásakor használja a megfelelő formátumjelölőket. A %p használatával hexadecimális mutatókat nyomtathat. Ez a legjobb választás a mutatók nyomtatásához. A Microsoft Visual C++ támogatja a %I a polimorf adatok nyomtatásához. A Visual C++ %I64 bites értékek nyomtatását is támogatja.