Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Tänk på följande när du porterar koden:
Följande antagande är inte längre giltigt:
#ifdef _WIN32 // Win32 code ... #else // Win16 code ... #endif64-bitarskompilatorn definierar dock _WIN32 för bakåtkompatibilitet.
Följande antagande är inte längre giltigt:
#ifdef _WIN16 // Win16 code ... #else // Win32 code ... #endifI det här fallet kan else-satsen representera _WIN32 eller _WIN64.
Var försiktig med justering av datatyp. Makrot TYPE_ALIGNMENT returnerar justeringskraven för en datatyp. Till exempel:
TYPE_ALIGNMENT( KFLOATING_SAVE )== 4 på x86, 8 på Intel Itanium-processorTYPE_ALIGNMENT( UCHAR )== 1 överalltTill exempel kernelkod som för närvarande ser ut så här:
ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );bör förmodligen ändras till:
ProbeForRead( UserBuffer, UserBufferLength, TYPE_ALIGNMENT(IOCTL_STRUC) );Automatiska korrigeringar av undantag för kernellägesjustering inaktiveras för Intel Itanium-system.
Var försiktig med NOT-åtgärder. Tänk på följande:
UINT_PTR a; ULONG b; a = a & ~(b - 1);Problemet är att ~(b–1) producerar "0x0000 0000 xxxx xxxx" och inte "0xFFFF FFFF xxxx xxxx". Kompilatorn identifierar inte detta. Åtgärda detta genom att ändra koden på följande sätt:
a = a & ~((UINT_PTR)b - 1);Var försiktig med att utföra osignerade och signerade åtgärder. Tänk på följande:
LONG a; ULONG b; LONG c; a = -10; b = 2; c = a / b;Resultatet är oväntat stort. Regeln är att om någon av operanderna är osignerade, är resultatet osignerat. I föregående exempel konverteras en till ett osignerat värde, dividerat med b och resultatet som lagras i c. Konverteringen innebär ingen numerisk manipulering.
Som ett annat exempel bör du tänka på följande:
ULONG x; LONG y; LONG *pVar1; LONG *pVar2; pVar2 = pVar1 + y * (x - 1);Problemet uppstår eftersom x är osignerat, vilket gör hela uttrycket osignerat. Detta fungerar bra om inte y är negativt. I det här fallet konverteras y till ett osignerat värde, uttrycket utvärderas med 32-bitars precision, skalas och läggs till i pVar1. Ett 32-bitars osignerat negativt tal blir ett stort 64-bitars positivt tal, vilket ger fel resultat. Åtgärda problemet genom att deklarera x som ett signerat värde eller uttryckligen skriva det till LONG- i uttrycket.
Var försiktig när du gör bitstorleksallokeringar. Till exempel:
struct xx { DWORD NumberOfPointers; PVOID Pointers[100]; };Följande kod är fel eftersom kompilatorn fyller strukturen med ytterligare 4 byte för att göra justeringen på 8 byte:
malloc(sizeof(DWORD) + 100*sizeof(PVOID));Följande kod är korrekt:
malloc(offsetof(struct xx, Pointers) + 100*sizeof(PVOID));Skicka inte
(HANDLE)0xFFFFFFFFtill funktioner som CreateFileMapping. Använd i stället INVALID_HANDLE_VALUE.Använd rätt formatspecificerare när du skriver ut en sträng. Använd %p för att skriva ut pekare i hexadecimalt. Det här är det bästa valet för att skriva ut pekare. Microsoft Visual C++ stöder %I för att skriva ut polymorfa data. Visual C++ stöder också %I64 för att skriva ut värden som är 64 bitar.