Exemple de code se comportant différemment sur Mac OS et Windows

- exemples de code se comportant différemment sur GCC et Visual :

1) while(*unsignedCharPtr) *unsignedCharPtr = maj[*unsignedCharPtr++];

-> dans Visual, la valeur (de type unsigned char) pointée par unsignedCharPtr est remplacée par la majuscule lui correspondant puis le pointeur est positionné sur le caractère suivant.
-> avec GCC, le pointeur est incrémenté avant l’affectation, par exemple « abcdef » devient « AAAAA… », ce qui n’est pas le résultat attendu, mais surtout on provoque un dépassement de tableau, donc un crash, car *unsignedCharPtr est modifiée avant d’être testée.
-> le bon code serait :
while(*unsignedCharPtr) *unsignedCharPtr++ = maj[*unsignedCharPtr];

-> une meilleure solution serait d’encapsuler cette ligne dans une fonction inline pour la raison évoquée plus loin.

Remarque : une ligne plus compacte serait (ne pas oublier le point-virgule) :
while((*unsignedCharPtr++ = maj[*unsignedCharPtr]));

2) void f(unsigned char* unsignedCharPtr) { …; *unsignedCharPtr = ‘a’; …; }

-> dans Visual, si cette fonction est utilisée avec une chaîne littérale
(par exemple f(« aaa »)), l’affectation est ignorée.

-> avec GCC, l’affectation conduit à un crash. Il ne s’agit pas d’une erreur de la part du compilateur, mais d’une prévention contre les failles puisque le pointeur représente une adresse invalide, qui pourrait pointer vers absolument n’importe où en mémoire. Ce genre de code étant plutôt difficile à identifier lors d’une recherche de bug, on peut toujours implémenter une exception.

-> le compilateur étant configuré par défaut pour refuser l’appel si le paramètre
est un const unsigned char* au lieu de unsigned char*, il ne faut surtout pas désactiver le signalement d’erreur. Le code ne compilera pas mais vous pouvez toujours appliquer un cast sur le paramètre, au cas par cas uniquement, ce qui reste tout de même déconseillé.

Social tagging: > > >

Laisser un commentaire