Considérations supplémentaires
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 ... #endif
Toutefois, 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 ... #endif
Dans 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 processeurTYPE_ALIGNMENT( UCHAR )
Intel Itanium == 1 partoutPar exemple, le code du noyau qui ressemble actuellement à ceci :
ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );
doit 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 xxxx » et non « 0xFFFF FFFF xxxx xxxx ». Le compilateur ne détecte pas cela. Pour résoudre ce problème, modifiez le code comme suit :
a = a & ~((UINT_PTR)b - 1);
Soyez prudent en effectuant 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 ampleur 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, a est converti en valeur non signée, divisée par b, et le résultat est stocké dans c. La conversion n’implique aucune manipulation numérique.
Comme autre exemple, considérez les é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 d’une précision 32 bits, mise à l’échelle et ajoutée à pVar1. Un nombre négatif non signé 32 bits devient un grand nombre positif de 64 bits, ce qui donne un résultat incorrect. Pour résoudre ce problème, déclarez x en tant que valeur signée ou saisissez-la explicitement en 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 va compléter la structure avec 4 octets supplémentaires pour effectuer 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 à des
(HANDLE)0xFFFFFFFF
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 imprimer des 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.
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour