Sdílet prostřednictvím


Další důležité informace

Při přenosu kódu zvažte následující body:

  • Následující předpoklad už není platný:

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

    64bitový kompilátor však definuje _WIN32 pro zpětnou kompatibilitu.

  • Následující předpoklad už není platný:

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

    V tomto případě může klauzule else představovat _WIN32 nebo _WIN64.

  • Při zarovnání datového typu buďte opatrní. Makro TYPE_ALIGNMENT vrátí požadavky na zarovnání datového typu. Příklad: TYPE_ALIGNMENT( KFLOATING_SAVE ) == 4 v procesoru x86, 8 na procesoru Intel ItaniumTYPE_ALIGNMENT( UCHAR ) == 1 všude.

    Například kód jádra, který aktuálně vypadá takto:

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

    měla by být pravděpodobně změněna na:

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

    Automatické opravy výjimek zarovnání v režimu jádra jsou pro systémy Intel Itanium zakázané.

  • Buďte opatrní při neprovozních operacích. Vezměte v úvahu následující skutečnosti:

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

    Problémem je, že ~(b–1) vytvoří "0x0000 0000 xxxx xxxx" a ne "0xFFFF FFFF xxxx". Kompilátor to nezjistí. Pokud chcete tento problém vyřešit, změňte kód následujícím způsobem:

    a = a & ~((UINT_PTR)b - 1);
    
  • Buďte opatrní při provádění nepodepsaných a podepsaných operací. Vezměte v úvahu následující skutečnosti:

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

    Výsledek je neočekávaně velký. Pravidlo znamená, že pokud je některý z operandů nepodepsaný, výsledek je nepodepsaný. V předchozím příkladu se převede na nepodepsanou hodnotu, vydělí se b a výsledek uložený v jazyce c. Převod nezahrnuje žádnou číselnou manipulaci.

    Jako další příklad zvažte následující:

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

    K tomuto problému dochází, protože x je nepodepsaný, a proto je celý výraz nepodepsaný. To funguje správně, pokud není y negativní. V tomto případě se y převede na nepodepsanou hodnotu, výraz se vyhodnotí pomocí 32bitové přesnosti, měřítka a přidaného do pVar1. 32bitové záporné číslo bez znaménka se stane velkým 64bitovým kladným číslem, které vrátí nesprávný výsledek. Chcete-li tento problém vyřešit, deklarujte x jako podepsanou hodnotu nebo explicitně zadejte ji do LONG ve výrazu.

  • Při přidělování kusmeálních velikostí buďte opatrní. Například:

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

    Následující kód je nesprávný, protože kompilátor vloží strukturu s dalšími 4 bajty, aby se zarovnání 8 bajtů:

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

    Následující kód je správný:

    malloc(offsetof(struct xx, Pointers) + 100*sizeof(PVOID));
    
  • Nepředávejte (HANDLE)0xFFFFFFFF funkcím, jako je CreateFileMapping. Místo toho použijte INVALID_HANDLE_VALUE.

  • Při tisku řetězce použijte specifikátory správného formátu. K tisku ukazatelů v šestnáctkovém formátu použijte %p. To je nejlepší volba pro tisk ukazatelů. Microsoft Visual C++ podporuje %I k tisku polymorfních dat. Visual C++ také podporuje %I64 k tisku hodnot, které jsou 64 bitů.