J'ai la fonction suivante pour lire un quadword big-endian (dans un fichier de base abstraite de classe I/O):Décalage négatif ou erreur trop importante - solution correcte?
unsigned long long File::readBigEndQuadWord(){
unsigned long long qT = 0;
qT |= readb() << 56;
qT |= readb() << 48;
qT |= readb() << 40;
qT |= readb() << 32;
qT |= readb() << 24;
qT |= readb() << 16;
qT |= readb() << 8;
qT |= readb() << 0;
return qT;
}
Les fonctions readb() lit un BYTE. Voici les typedefs utilisés:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
La chose est que je reçois 4 avertissements du compilateur sur les quatre premières lignes avec l'opération de changement:
avertissement C4293: « < < »: compte de décalage négatif ou trop grand, le comportement non défini
Je comprends pourquoi cet avertissement se produit, mais je ne peux pas sembler comprendre comment se débarrasser correctement. Je pourrais faire quelque chose comme:
qT |= (unsigned long long)readb() << 56
;
Cela supprime l'avertissement, mais n'y a-t-il pas d'autres problèmes, le BYTE sera-t-il correctement étendu tout le temps? Peut-être que je n'y pense que trop et que la solution est aussi simple. Pouvez-vous m'aider ici? Merci.
Merci pour votre réponse. J'ai moi-même pensé que le compilateur devrait être assez intelligent pour voir que je l'attribue à une variable assez grande pour contenir toutes les données (j'utilise MSVS2008). Mais l'avertissement a soulevé des doutes sur l'exactitude de mon code, alors j'ai demandé ici. – PeterK
Si le compilateur a compris ce que vous faites avec le résultat et change les types intermédiaires en conséquence, alors il viole la norme du langage. La promotion de type est bien définie et le type de résultat d'un opérateur dépend uniquement des types d'opérandes. –
En mars 2015, la compilation d'un tel code avec MSVC 2013 produisait toujours l'avertissement. – Yadli