Weitere Überlegungen
Berücksichtigen Sie beim Portieren Ihres Codes die folgenden Punkte:
Die folgende Annahme ist nicht mehr gültig:
#ifdef _WIN32 // Win32 code ... #else // Win16 code ... #endif
Der 64-Bit-Compiler definiert jedoch _WIN32 für die Abwärtskompatibilität.
Die folgende Annahme ist nicht mehr gültig:
#ifdef _WIN16 // Win16 code ... #else // Win32 code ... #endif
In diesem Fall kann die else-Klausel _WIN32 oder _WIN64 darstellen.
Seien Sie vorsichtig bei der Datentypausrichtung. Das TYPE_ALIGNMENT Makro gibt die Ausrichtungsanforderungen eines Datentyps zurück. Beispiel:
TYPE_ALIGNMENT( KFLOATING_SAVE )
== 4 auf x86, 8 auf Intel Itanium-ProzessorTYPE_ALIGNMENT( UCHAR )
== 1 überallBeispiel: Kernelcode, der derzeit wie folgt aussieht:
ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );
sollte wahrscheinlich in geändert werden:
ProbeForRead( UserBuffer, UserBufferLength, TYPE_ALIGNMENT(IOCTL_STRUC) );
Automatische Korrekturen von Kernelmodusausnahmen sind für Intel Itanium-Systeme deaktiviert.
Seien Sie vorsichtig mit NOT-Vorgängen. Beachten Sie Folgendes:
UINT_PTR a; ULONG b; a = a & ~(b - 1);
Das Problem besteht darin, dass ~(b–1) "0x0000 0000 xxxx xxxx" und nicht "0xFFFF FFFF xxxx xxxx" erzeugt. Der Compiler erkennt dies nicht. Um dies zu beheben, ändern Sie den Code wie folgt:
a = a & ~((UINT_PTR)b - 1);
Achten Sie darauf, unsignierte und signierte Vorgänge auszuführen. Beachten Sie Folgendes:
LONG a; ULONG b; LONG c; a = -10; b = 2; c = a / b;
Das Ergebnis ist unerwartet groß. Die Regel lautet: Wenn ein Operand nicht signiert ist, ist das Ergebnis nicht signiert. Im vorherigen Beispiel wird a in einen wert ohne Vorzeichen konvertiert, dividiert durch b, und das Ergebnis wird in c gespeichert. Die Konvertierung beinhaltet keine numerische Bearbeitung.
Betrachten Sie als weiteres Beispiel Folgendes:
ULONG x; LONG y; LONG *pVar1; LONG *pVar2; pVar2 = pVar1 + y * (x - 1);
Das Problem tritt auf, weil x ohne Vorzeichen ist, wodurch der gesamte Ausdruck unsigniert ist. Dies funktioniert gut, es sei denn, y ist negativ. In diesem Fall wird y in einen wert ohne Vorzeichen konvertiert, der Ausdruck wird mit 32-Bit-Genauigkeit ausgewertet, skaliert und pVar1 hinzugefügt. Eine 32-Bit-Negative Zahl ohne Vorzeichen wird zu einer großen positiven 64-Bit-Zahl, die das falsche Ergebnis liefert. Um dieses Problem zu beheben, deklarieren Sie x als signierten Wert oder geben Sie es explizit in LONG im Ausdruck aus.
Seien Sie beim Erstellen von Stückgrößenzuordnungen vorsichtig. Beispiel:
struct xx { DWORD NumberOfPointers; PVOID Pointers[100]; };
Der folgende Code ist falsch, da der Compiler die Struktur mit zusätzlichen 4 Bytes unterbindet, um die 8-Byte-Ausrichtung vorzunehmen:
malloc(sizeof(DWORD) + 100*sizeof(PVOID));
Der folgende Code ist richtig:
malloc(offsetof(struct xx, Pointers) + 100*sizeof(PVOID));
Übergeben
(HANDLE)0xFFFFFFFF
Sie nicht an Funktionen wie CreateFileMapping. Verwenden Sie stattdessen INVALID_HANDLE_VALUE.Verwenden Sie beim Drucken einer Zeichenfolge die richtigen Formatbezeichner. Verwenden Sie %p, um Zeiger in Hexadezimal zu drucken. Dies ist die beste Wahl zum Drucken von Zeigern. Microsoft Visual C++ unterstützt %I zum Drucken polymorpher Daten. Visual C++ unterstützt auch %I64 zum Drucken von Werten mit 64 Bit.