Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Podczas przenoszenia kodu należy wziąć pod uwagę następujące kwestie:
Następujące założenie nie jest już prawidłowe:
#ifdef _WIN32 // Win32 code ... #else // Win16 code ... #endifJednak kompilator 64-bitowy definiuje _WIN32 na potrzeby zgodności z poprzednimi wersjami.
Następujące założenie nie jest już prawidłowe:
#ifdef _WIN16 // Win16 code ... #else // Win32 code ... #endifW takim przypadku klauzula else może reprezentować _WIN32 lub _WIN64.
Zachowaj ostrożność przy wyrównaniu typu danych. Makro TYPE_ALIGNMENT zwraca wymagania dotyczące wyrównania typu danych. Na przykład:
TYPE_ALIGNMENT( KFLOATING_SAVE )== 4 na procesorze x86, 8 na procesorze Intel ItaniumTYPE_ALIGNMENT( UCHAR )== 1 wszędzieNa przykład kod jądra, który obecnie wygląda następująco:
ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );prawdopodobnie należy zmienić na:
ProbeForRead( UserBuffer, UserBufferLength, TYPE_ALIGNMENT(IOCTL_STRUC) );Automatyczne poprawki wyjątków wyrównania trybu jądra są wyłączone dla systemów Intel Itanium.
Zachowaj ostrożność przy użyciu operacji NOT. Rozważ następujące kwestie:
UINT_PTR a; ULONG b; a = a & ~(b - 1);Problem polega na tym, że ~(b–1) generuje wartość "0x0000 0000 xxxx xxxx", a nie "0xFFFF FFFF xxxx xxxx". Kompilator nie wykryje tego. Aby rozwiązać ten problem, zmień kod w następujący sposób:
a = a & ~((UINT_PTR)b - 1);Zachowaj ostrożność podczas wykonywania niepodpisanych i podpisanych operacji. Rozważ następujące kwestie:
LONG a; ULONG b; LONG c; a = -10; b = 2; c = a / b;Wynik jest nieoczekiwanie duży. Reguła polega na tym, że jeśli którykolwiek operand jest niepodpisany, wynik jest niepodpisany. W poprzednim przykładzie element a jest konwertowany na niepodpisaną wartość podzieloną przez b i wynik przechowywany w języku c. Konwersja nie obejmuje manipulacji liczbowej.
W innym przykładzie rozważ następujące kwestie:
ULONG x; LONG y; LONG *pVar1; LONG *pVar2; pVar2 = pVar1 + y * (x - 1);Problem występuje, ponieważ x jest niepodpisane, co sprawia, że całe wyrażenie niepodpisane. To działa dobrze, chyba że y jest ujemne. W tym przypadku wartość y jest konwertowana na wartość niepodpisaną, wyrażenie jest obliczane przy użyciu dokładności 32-bitowej, skalowanej i dodawanej do zmiennej pVar1. 32-bitowa liczba ujemna bez znaku staje się dużą 64-bitową liczbą dodatnią, co daje niewłaściwy wynik. Aby rozwiązać ten problem, zadeklaruj wartość x jako wartość ze znakiem lub jawnie wpisz go, aby long w wyrażeniu.
Należy zachować ostrożność podczas tworzenia alokacji rozmiaru kawałków. Na przykład:
struct xx { DWORD NumberOfPointers; PVOID Pointers[100]; };Poniższy kod jest nieprawidłowy, ponieważ kompilator wyścieła strukturę z dodatkowymi 4 bajtami, aby wyrównać 8 bajtów:
malloc(sizeof(DWORD) + 100*sizeof(PVOID));Następujący kod jest poprawny:
malloc(offsetof(struct xx, Pointers) + 100*sizeof(PVOID));Nie przekazuj
(HANDLE)0xFFFFFFFFdo funkcji, takich jak CreateFileMapping. Zamiast tego użyj INVALID_HANDLE_VALUE.Użyj odpowiednich specyfikatorów formatu podczas drukowania ciągu. Użyj %p, aby wydrukować wskaźniki w szesnastkowym. Jest to najlepszy wybór w przypadku wskaźników drukowania. Program Microsoft Visual C++ obsługuje %I drukowania danych polimorficznych. Język Visual C++ obsługuje również %I64 do drukowania wartości, które są 64-bitowe.