Pensez à
#include <iostream>
int main()
{
double a = 1.0 / 0;
double b = -1.0 / 0;
double c = 0.0 / 0;
std::cout << a << b << c; // to stop compilers from optimising out the code.
}
J'ai toujours pensé que a
sera +Inf, b
sera -Inf, et c
sera NaN. Mais j'ai également entendu des rumeurs selon lesquelles le comportement de la division par zéro en virgule flottante est, à strictement parler, le suivant indéfini et donc le code ci-dessus ne peut pas être considéré comme du C++ portable. (Cela oblitère théoriquement l'intégrité de ma pile de code de plus d'un million de lignes. Oups).
Qui a raison ?
Je suis satisfait de la note mise en œuvre définie mais je parle de manger des chats, d'aspirer des démons comportement indéfini ici.
1 votes
Umm : "Voulez-vous dire
std::cout << a << b << c;
" ?1 votes
@WhiZTiM : naturellement ;-)
2 votes
@WhiZTiM Je l'ai vu. Nous l'avons tous vu. Je suis désolé mais vous n'êtes pas un grand Google ;)
0 votes
Cela ne dépend-il pas de l'implémentation de la virgule flottante que votre compilateur choisit d'utiliser ?
0 votes
C'est en effet le cas, mais l'implémentation en virgule flottante doit obéir à certaines règles.
0 votes
Votre base de code dépend-elle réellement de l'infini et de NaN ?
0 votes
Non, mais dans certaines conditions, ils peuvent être produits (par exemple, un analyseur syntaxique d'expression - par exemple, un paiement de dérivé financier - qui pourrait être mal formé par un utilisateur).
5 votes
Compilateur décent ne compilera même pas votre code .
0 votes
@KerrekSB c'est une réponse aussi bonne que n'importe laquelle des réponses existantes.
1 votes
@KerretSB : melpon.org/wandbox/permlink/9c11BxUhoe10vfpr
0 votes
KerreckSB - très raisonnable - fait passer les avertissements en erreurs. Il ne veut pas de Boost alors ;-)
0 votes
LOL "comportement indéfini de mangeur de chat" ?!?
0 votes
@NathanOliver : En pratique, oui, mais l'OP demande si c'est UB à la couche C++.
0 votes
@KerrekSB Il est intéressant de noter qu'il n'y a pas d'erreurs ou d'avertissements si vous écrivez
/ 0.0
à la place.0 votes
@GhostCat : Un de ceux-là. fr.wikipedia.org/wiki/British_Rail_Class_43_(HST)
0 votes
Choo choo est entré dans un tunnel et ma "demande" de suppression n'a pas atteint le serveur.
0 votes
@KerrekSB Cela n'a rien à voir avec le compilateur en soi ; cela a à voir avec l'activation des avertissements et leur transformation en erreurs. Vous pourriez tout aussi bien passer
-Wno-div-by-zero
pour désactiver cet avertissement.0 votes
@Pryftan : Eh bien, le point est que le code a un comportement non défini, ce qui est un peu malheureux. Les normes de virgule flottante comme IEEE754 spécifient de telles opérations, mais la norme C++ ne le fait pas. C'est donc à vous (et à votre compilateur) de décider comment vous voulez gérer cet UB.
0 votes
@KerrekSB Assez juste. Je n'aime pas beaucoup le C++ (mauvaise réaction ?), mais seulement le C (bien que j'aie utilisé le C++). De toute façon, je suis un penseur littéral, c'est pourquoi mon commentaire (probablement un commentaire injuste, mais j'ai quand même senti qu'il était nécessaire de souligner que le compilateur lui-même n'est pas le problème autant que l'agressivité du compilateur avec ses avertissements/erreurs).
0 votes
@Pryftan : Notez qu'en C aussi c'est un comportement indéfini de diviser par zéro (cf. C11 6.5.5p5).
0 votes
@KerrekSB Je n'ai jamais suggéré que ce n'était pas le cas. Je disais qu'en ce qui concerne le C++, je ne m'en soucie guère. Je pensais qu'il était antérieur à C11, mais la façon dont vous le dites me fait penser que ce n'est peut-être pas le cas (ou alors vous avez juste accès à la littérature pour C11).