Chasse au débordement d'unsigned int : Détective C++ du débutant au pro

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Piège pour les inattentifs : pourquoi unsigned int est une bombe à retardement ?

\n\n

Chaque développeur C++ rencontre tôt ou tard une situation où les nombres se comportent comme des lapins en colère — ils sautent sans cesse du positif à zéro. Il s'agit du débordement de unsigned int. Contrairement à son homologue signé (signed int), le débordement de unsigned en C++ est strictement défini par la norme — ce n'est pas un UB (comportement indéfini). Le nombre s'enroule simplement modulo 2N. Mais cela ne rend pas l'erreur moins fatale.

\n\n

Imaginez : vous calculez le solde d'un compte, le nombre d'éléments dans un tableau ou le temps de fonctionnement d'un minuteur. Un débordement accidentel, et la logique de l'application s'effondre. La question du titre "How do I detect unsigned integer overflow?" a rassemblé des milliers de vues sur Stack Overflow pour une bonne raison. Analysons trois approches pour détecter le débordement : de la naïve (mais fonctionnelle) à la professionnelle.

\n\n

Pourquoi les vérifications standard ne fonctionnent-elles pas ?

\n\n

La première chose qui vient à l'esprit d'un débutant :

\n\n
unsigned int a = UINT_MAX;\nunsigned int b = 1;\nif (a + b < a) // Vérification naïve\n    std::cout << "Débordement !";
\n\n

Ce code fonctionne, mais seulement pour l'addition. Pour la multiplication, la soustraction ou les types mixtes, la logique se brise. De plus, le compilateur peut considérer une telle vérification comme redondante et la supprimer lors de l'optimisation. Surtout si les types sont signés. Ne comptez pas sur la magie — écrivez explicitement.

\n\n

Approche n°1 : Arithmétique avant l'opération (Pre-check)

\n\n

La méthode la plus fiable est de vérifier la possibilité d'un débordement avant d'effectuer l'opération. Pour l'addition de deux nombres non signés, la condition est simple :

\n\n

Si a + b peut déborder, alors a > (UINT_MAX - b).

\n\n
#include <climits>\n#include <iostream>\n\nbool will_add_overflow(unsigned int a, unsigned int b) {\n    return a > UINT_MAX - b;\n}\n\nint main() {\n    unsigned int x = 4000000000;\n    unsigned int y = 500000000;\n    \n    if (will_add_overflow(x, y)) {\n        std::cerr << "Erreur : débordement lors de l'addition !\\n";\n    } else {\n        std::cout << "Résultat : " << x + y << "\\n";\n    }\n    return 0;\n}
\n\n

Multiplication — plus complexe

\n

Pour la multiplication, la vérification est un peu plus délicate : a > UINT_MAX / b (et n'oubliez pas la division par zéro).

\n\n
bool will_mult_overflow(unsigned int a, unsigned int b) {\n    if (b == 0) return false; // Multiplication par zéro — sûr\n    return a > UINT_MAX / b;\n}
\n\n

Avantages : Multiplateforme, contrôle total, aucune dépendance cachée.
\nInconvénients : Nécessité d'écrire des fonctions séparées pour chaque opération. Le code devient volumineux.

\n\n

Approche n°2 : Vérification après l'opération (Post-check)

\n\n

La norme C++ garantit que pour les types unsigned, le résultat d'une opération est (a + b) mod 2^N. Par conséquent, nous pouvons effectuer l'opération, puis vérifier si la valeur a "enroulé".

\n\n
#include <iostream>\n#include <limits>\n\ntemplate<typename T>\nbool add_overflow(T a, T b, T& result) {\n    result = a + b;\n    return result < a; // Astuce clé\n}\n\nint main() {\n    unsigned int res;\n    if (add_overflow(4000000000u, 500000000u, res)) {\n        std::cout << "Débordement détecté !\\n";\n    } else {\n        std::cout << "OK : " << res << "\\n";\n    }\n    return 0;\n}
\n\n

Important : Cette astuce fonctionne uniquement si a et b sont du même type non signé. Pour uint32_t — parfait. Pour un mélange de unsigned int et int — échec.

\n\n

Piège pour la soustraction

\n

Pour la soustraction, la condition est inverse : result > a.

\n\n
template<typename T>\                

Blogs

Book Recommendations