Comment détecter les nombres négatifs comme des erreurs d’parsing lors de la lecture d’entiers non signés?

Je souhaite lire des entiers non signés dans une représentation en base 10 (décimale) à partir d’un iostream C ++ avec une détection d’erreur au moins rudimentaire. À mon avis, les signes moins seraient clairement une erreur dans ce cas, car les entiers non signés n’ont pas de signe. Cependant, le gcc est d’un avis différent:

#include  #include  int main() { std::ssortingngstream a("5"), b("-0"), c("-4"); unsigned int i; a >> i; if ( a ) std::cout << i << std::endl; else std::cout << "Conversion failure" <> i; if ( b ) std::cout << i << std::endl; else std::cout << "Conversion failure" <> i; if ( c ) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl; return 0; } 

me donne une sortie de

 4294967292 

pour la dernière ligne, comme si un entier signé -4 avait été lu et converti en unsigned int.

Apparemment, les gens de GCC voient cela comme une caractéristique . Existe-t-il une norme qui impose ce comportement et existe-t-il un moyen d’écrire un parsingur syntaxique pour en sortir, c’est-à-dire détecter “-4” (et peut-être “-0”) comme des erreurs de conversion?

Selon les consultants de C ++ 03, 22.2.2.1.2 / 11, les formats sont hérités de scanf et de leurs amis, qui disent à leur tour que la séquence de caractères convertie est “éventuellement signée”, même pour ceux avec une sortie non signée. strtoul est le même.

Donc, je suppose que vous pourriez dire que la norme qui impose le comportement est C89 pour C ++ 03, C99 pour C ++ 11.

Etant donné que le - n’est autorisé que comme premier caractère, je suppose que la solution consiste à le vérifier en peek un peek d’ peek avant d’utiliser l’ operator>> .

Si je lis correctement 22.2.2.1.2 / table 5, cela montre que l’extraction dans un unsigned équivaut à scanf avec %u qui semble également effectuer la conversion négatif -> positif.

Serait-ce vraiment différent si vous l’aviez fait?

 int i; unsigned int u; c >> i; u = i; std :: cout << u; 

Peu importe que l' operator>> tolère l'inadéquation des signes car les règles C sous-jacentes autoriseront une conversion silencieuse dans tous les cas. Vous n’ajoutez pas fondamentalement de sécurité en "renforçant" l’opérateur de saisie.

Cela dit, mon gcc (4.3.5 sous Solaris) dit que c'est une erreur de conversion.