Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Lors du portage de votre code, tenez compte des points suivants :
L’hypothèse suivante n’est plus valide :
#ifdef _WIN32 // Win32 code ... #else // Win16 code ... #endifToutefois, le compilateur 64 bits définit _WIN32 pour la compatibilité descendante.
L’hypothèse suivante n’est plus valide :
#ifdef _WIN16 // Win16 code ... #else // Win32 code ... #endifDans ce cas, la clause Else peut représenter _WIN32 ou _WIN64.
Soyez prudent avec l’alignement du type de données. La macro TYPE_ALIGNMENT retourne les exigences d’alignement d’un type de données. Par exemple :
TYPE_ALIGNMENT( KFLOATING_SAVE )== 4 sur x86, 8 sur le processeur Intel ItaniumTYPE_ALIGNMENT( UCHAR )== 1 partoutPar exemple, le code du noyau qui ressemble actuellement à ceci :
ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );devrait probablement être remplacé par :
ProbeForRead( UserBuffer, UserBufferLength, TYPE_ALIGNMENT(IOCTL_STRUC) );Les correctifs automatiques des exceptions d’alignement en mode noyau sont désactivés pour les systèmes Intel Itanium.
Soyez prudent avec les opérations NOT. Tenez compte des éléments suivants :
UINT_PTR a; ULONG b; a = a & ~(b - 1);Le problème est que ~(b-1) produit « 0x0000 0000 xxxx » et non « 0xFFFF FFFF xxxx xxxx ». Le compilateur ne le détecte pas. Pour résoudre ce problème, modifiez le code comme suit :
a = a & ~((UINT_PTR)b - 1);Veillez à effectuer des opérations non signées et signées. Tenez compte des éléments suivants :
LONG a; ULONG b; LONG c; a = -10; b = 2; c = a / b;Le résultat est d’une taille inattendue. La règle est que si l’un des opérandes n’est pas signé, le résultat n’est pas signé. Dans l’exemple précédent, une valeur non signée est convertie en valeur non signée, divisée par b et le résultat stocké dans c. La conversion n’implique aucune manipulation numérique.
En guise d’autre exemple, tenez compte des éléments suivants :
ULONG x; LONG y; LONG *pVar1; LONG *pVar2; pVar2 = pVar1 + y * (x - 1);Le problème se produit parce que x n’est pas signé, ce qui rend l’expression entière non signée. Cela fonctionne bien, sauf si y est négatif. Dans ce cas, y est converti en valeur non signée, l’expression est évaluée à l’aide de la précision 32 bits, mise à l’échelle et ajoutée à pVar1. Un nombre négatif non signé 32 bits devient un grand nombre positif 64 bits, ce qui donne un résultat incorrect. Pour résoudre ce problème, déclarez x comme valeur signée ou tapez-la explicitement dans long dans l’expression.
Soyez prudent lorsque vous effectuez des allocations de taille fragmentaire. Par exemple:
struct xx { DWORD NumberOfPointers; PVOID Pointers[100]; };Le code suivant est incorrect, car le compilateur remplira la structure avec un nombre supplémentaire de 4 octets pour rendre l’alignement de 8 octets :
malloc(sizeof(DWORD) + 100*sizeof(PVOID));Le code suivant est correct :
malloc(offsetof(struct xx, Pointers) + 100*sizeof(PVOID));Ne passez pas
(HANDLE)0xFFFFFFFFaux fonctions telles que CreateFileMapping. Utilisez plutôt INVALID_HANDLE_VALUE.Utilisez les spécificateurs de format appropriés lors de l’impression d’une chaîne. Utilisez %p pour imprimer des pointeurs en hexadécimal. Il s’agit du meilleur choix pour l’impression de pointeurs. Microsoft Visual C++ prend en charge %I pour imprimer des données polymorphes. Visual C++ prend également en charge %I64 pour imprimer des valeurs de 64 bits.