Bonjour,
Je voulais comment d�tecter un overflow sur une op�ration sur des int.
Je ne code pas, c'est juste une interrogation.
Version imprimable
Bonjour,
Je voulais comment d�tecter un overflow sur une op�ration sur des int.
Je ne code pas, c'est juste une interrogation.
Bonjour
D�sol� on ne peut pas. (unsigned short)65535 + 1 donnera 0 sans que tu ne puisses d�tecter si c'est normal ou pas. Enfin le terme "normal" est mal utilis� car c'est en r�alit� tout � fait normal (le "1" qui se trouve sur le 33� bit n'est pas r�cup�r�) mais tu ne peux pas d�tecter si la valeur officielle devait �tre 65536 ou 0.
Merci pour le retour.
C'�tait ce qu'il me semblait avoir compris, mais j�avais l'impression de comprendre de travers.
Surprenant qu'on ne puisse d�tecter un overflow, je trouve m�me �a probl�matique.
C'est tir� de la conception du C: son but clairement d�fini est d'aller le plus vite possible. Et pour cela il ne v�rifie rien, absolument rien. Je peux �crire char *pt=(char*)123 puis aller voir printf("%d", *pt) je n'aurai aucun souci de compilation.
C'est effectivement probl�matique pour ceux qui sont habitu�s � travailler avec un langage rempli de garde-corps.
:mrgreen: bof, c'est surtout � l'ex�cution que le probl�me intervient.
L'exemple de @Sve@r est assez simple, et n'est s�rement pas repr�sentatif des "overflows".
Le compilateur peut faire la t�che mais pour combien de probl�mes ? 2% ? 20% ? 50% ? 70% ? 92% ?
Et c'est l'histoire du vol 501 d'Ariane 5 (<- lien Wikip�dia) "les valeurs trop �lev�es mesur�es par les acc�l�rom�tres ont provoqu� un d�passement de capacit�"
Le fait qu'un exemple soit simple est souvent une bonne chose, non ? :P
C'est vrai, il se voulait plut�t repr�sentatif des erreurs d'adressage non d�tect�es et qui provoquent un UB. Parce que pour l'overflow effectivement, sauf � "voir" que la valeur finale est plus petite que la valeur d'origine (on pr�sume que celle-ci est cens�e cro�tre dans l'op�ration) il n'y a pas d'erreur � l'ex�cution (ni m�me de UB).
Un de mes profs d'info avait parl� de sinus n�gatif calcul� en unsigned (l�gende urbaine issue du t�l�phone arabe probablement) et le lien wiki est plus pr�cis. Ou alors il parlait d'un autre crash...
Les languages C et C++ ne v�rifient pas les d�passements de capacit�s des types fondamentaux. D'autres languages vont pr�venir avec par exemple une exception. Mais est-ce vraiment mieux?
Le code peut difficilement "corriger" le probl�me et aboutit finalement � un arr�t du programme.
Si on prend le cas du vol 501 d'Ariane, il y aurait eu signalement imm�diat de l'anomalie (au lieu d'une anomalie d�tect�e indirectement) pour arriver finalement au m�me probl�me :roll:
Justement, je connais le probl�me de l'Ariane. A l'�poque, ma soci�t� participait � la qualification de modules d'Ariane (pas celui incrimin� ici). Et pour pr�ciser ce que dit Wikip�dia, l'�volution du mat�riel a bien �t� requalifi�e. On a eu alors des pr�cisions en particulier sur le contr�le calibration indiqu� �videmment comme non actif pendant le vol. En fait les r�sultats n'�taient pas utilis�s, mais ses erreurs, elles, continuaient de remonter.
Le principal probl�me est, selon moi, l'ambigu�t� sur "le contr�le calibration est d�sactiv�" (est-ce un retrait total, la non utilisation des r�sultats, les erreurs trait�es m�me si l'utilisation est d�sactiv�e?)
Il y eu une cause additionnelle non cit�e dans l'article. La pr�paration a dur� plus que pr�vu, et la temp�rature du comburant �tait � la limite sup�rieure, d'o� une fluidit� plus grande, d'o� une pouss�e un peu sup�rieure � l'attendu. Peut-�tre que si on avait fait moins de pr�-contr�les, on n'aurait pas eu le probl�me :)
Bonjour,
Par rapport � la question initiale, n'y a t-il pas un moyen avec les registres CPU (donc en assembleur ?). De m�moire, je pensais que la CPU allait mettre un flag � 1, en cas d'overflow.
https://wiki.sei.cmu.edu/confluence/...lt+in+overflow
https://gcc.gnu.org/onlinedocs/gcc/I...-Builtins.htmlCode:
1
2
3
4
5
6
7
8
9
10
11
12 #include <limits.h> void f(signed int si_a, signed int si_b) { signed int sum; if (((si_b > 0) && (si_a > (INT_MAX - si_b))) || ((si_b < 0) && (si_a < (INT_MIN - si_b)))) { /* Handle error */ } else { sum = si_a + si_b; } /* ... */ }
non ?Code:The compiler will attempt to use hardware instructions to implement these built-in functions where possible, like conditional jump on overflow after addition, conditional jump on carry etc.
Je me suis pos� la m�me question, il y a un bit dans un registre de la CPU qui est positionn� en cas de d�passement, c'est l'overflow flag. Mais je ne sais pas si c'est pertinent dans cette discussion.
Apparemment des fonctions internes � gcc pr�sentes dans le lien d'unanonyme permettent de g�rer l'overflow, mais je pense que ce n'est pas standard.Citation:
Uniquement si on peut le r�cup�rer en C
Ca n'est pas standard, je pense que c'est parce que �a n�cessite d'utiliser les bits sp�cifiques � chaque processeur (carry et overflow) et que certains processeur pouvaient ne pas avoir. C'est faisable sans, mais lourd pour la multiplication.
Mais la plupart des compilateurs ont bien impl�ment�s des fonctions intrins�ques pour cela.
Et le C++ semble avoir d�cid� que cette contrainte n'existe plus et fournit depuis C++26 : std::add_sat() std::sub_sat() std::mul_sat() std::div_sat() et std::saturate_cast<>(), �a devrait vraisemblablement aussi �voluer en C.
Pour une op�ration d'addition que tu sais peux overflow, tu peux manuellement la pr�venir - dans une certaine mesure.
Au lieu d'ajouter A + B puis v�rifier si �a a d�pass�, tu v�rifies d'abord que MAX - A > B
Bonjour,
La plupart des langages compil�s permettent d'inclure des instructions assembleurs et les CPU ont toutes une collections de flags qui se positionnent � la moindre op�ration classique (entendre pas SIMD). C'est donc possible.
Mais ce n'est pas n�cessairement souhaitable. Par exemple, si on doit v�rifier que la diff�rence entre 2 unsigned, Tnow - Tstart, reste en de�� d'une valeur dT, il est int�ressant de pouvoir �crire if(Tnow - Tstart < dT) sans se pr�occuper d'un overflow (il faut quand m�me que ce test soit r�it�r� avec une fr�quence compatible avec la taille des unsigned utilis�s).
Les options saturate ne corrigent pas le probl�me d'overflow mais le transforment : max + 1 = 0 devient max + 1 = max. En g�n�ral pour l'impl�menter � l'�conomie on utilise les instructions SIMD qui pr�voient ce type d'op�rations (ainsi qu'un certains nombre d'autres int�ressantes, la plupart �galement induites par l'absence de tests int�gr�s difficiles � impl�menter sur des vecteurs).
Salutations
Le pire, c'est que pour des entiers sign�s, l'overflow est un comportement ind�fini, tu ne peux donc m�me pas tester apr�s coup le r�sultat: Si la branche actuelle du code contient un calcul qui fait une overflow, tu as d�j� perdu, game over.
Heureusement, ce n'est pas le cas des entiers non-sign�s, donc dans certains cas tu peux faire des tests, du genre:
Malheureusement ceci est impossible avec des entiers sign�s, et je ne vois pas trop comment tester qu'une op�ration ne va pas causer d'overflow dans le cas de la multiplication.Code:
1
2
3
4
5
6
7
8
9 unsigned int multiplier(unsigned int a, unsigned int b) { unsigned int res = a*b; if(res/a != b || res/b != a) { //Oups! } return res; }
Diviser INT_MAX par la valeur absolue de chaque op�rande et comparer � l'autre? (en supposant qu'aucune op�rande ne peut valoir INT_MIN, qui n'a pas de valeur absolue -- d'un autre c�t� une multiplication de INT_MIN par n'importe quelle valeur autre que 0 ou 1 est garantie causer une overflow)
Bonjour,
La multiplication doit avoir un format d'accueil deux fois plus longs que les op�randes. M�me en 32 bits le r�sultat d'une multiplication �tait d�j� sur 64 bits (edx:eax) ce qui �vite sur les sign�s (et les non sign�) tous les d�passements y compris pour le -231 qu'il convient d'�viter pour d'autres raisons (relative ind�termination -imin = imin par exemple).
Le C est assez permissif pour permettre d'�crire un truc comme une multiplication de 2 entiers de 64 bits � ranger dans un octet. La multiplication se fera bien dans les r�gles de l'art en �tendant les 64 bits � 128 bits par concat�nation des registres rdx et rax donc sans risque d'overflow mais le casting sauvage qui s'en suivra fera une troncature classique mais d�sastreuse sans remord ni overflow.Code:imul edx = edx*eax résultat dans edx:eax
En r�sum� si on veut mettre les deux pieds dans le m�me soulier, il y a int�r�t � changer de pointure 8-)
Salutations
Ben en fait non ^^
Par exemple RISC-V n'a pas de register flag.
(Je crois que le MIPS aussi mais pas sur).
Le soucis du flag register sur les processeurs moderne, c'est qu'ils emp�chent certaine optimisation (o� plut�t les rend horriblement compliqu�), du coup les r�duire � certaine instruction (cmp) ou les virer comme le fait RISC-V rend le design du processeur plus simple et plus facilement optimisable.
Donc il est probable que dans l'avenir ce genre de flag register disparaisse sur les nouvelles conceptions d'ISA.
Et comment tu fais pour v�rifier une retenue ? un d�passement ?