IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

bug clang boucle infinie


Sujet :

C

  1. #21
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par foetus Voir le message
    Du code mort il y a le return qui même s'il est inatteignable, dit que cette branche peut être exécutée while -> for -> if -> return 1.
    Ce qui va être exécuté est le return 1. l’optimisateur de clang vas tout simplement virer une bonne partie du code de la boucle pour en faire une boucle while(1) {return 1;} ou un "do{ return 1; }while(1)" et comme cela ne sert rien, il remplacera le tout par un return 1; donc à partir d’un code mort du if, succédera une déduction qui pousse naturellement l’optimiseur à remplacer le code de test part

    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    test:
      mov eax, 0x1
      ret 
    ; padding ...
    Remarque qu'avec Gcc en mode statique en obtient le même résultat
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  2. #22
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Citation Envoyé par LucyFayry Voir le message
    le comportement est ok sans O3 mais avec O3 ça donne un programme qui fait pas le code. pour moi c'est un bug.
    ça dépend de un si ton code est UB.
    Et secundo je te rassure que GCC bug aussi avec -O3 ,peut être pas sur un target x86 , mais sur d'autre plateforme que j'ai fait GCC a de sacré bug

    J'ai envie aussi de dire qu'il faut pas prendre ces optimisations comme un truc "magique" , et on met les flag d'optimisation par rapport à ce qu'on souhaite faire.
    Pour ma part (et c'est ce que fait le kernel Linux aussi il me semble ) , on doit des fois annuler les optimisations du compilateur pour qu'une fonction soit "valide".

  3. #23
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Cela foutrait en l'air 90% des codes de la planète
    Mon pauvre... Si tu savais le nombre de code qui reposent sur des UB...



    Citation Envoyé par Kannagi Voir le message
    Et secundo je te rassure que GCC bug aussi avec -O3 ,peut être pas sur un target x86 , mais sur d'autre plateforme que j'ai fait GCC a de sacré bug
    C'est un classique les codes qui fonctionnent bien en O1 voire O2, et qui s'écroulent en O3... Il y a potentiellement des bugs compilo mais c'est surtout que tous les UB de ton code peuvent t'exploser à la figure. Cette discussion est intéressante : https://stackoverflow.com/questions/...dangerous-in-g

    Et il ne faut pas oublier que votre compilateur peut faire tout ce qu'il veut quand il rencontre un UB dans votre code : le laisser en O0, Og, O1, O2, Os, et le virer en O3. Quand il rencontre un UB, le gentil deal "Le minimum qu'on est en droit d'attendre d'un compilateur est qu'il reproduise en toutes circonstances fidèlement l'algorithme qu'on lui donne" décrit par Sve@r n'existe plus.

    Il y a une série incroyable sur le blog de LLVM : https://blog.llvm.org/2011/05/what-e...ould-know.html J'encourage vivement tout développeur qui n'est pas au clair sur les conséquences d'un UB à la lire. Vous aurez peur de coder après... Surtout quand on sait que quelque chose d'aussi bête qu'un overflow d'un int est un UB.

  4. #24
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Citation Envoyé par Bktero Voir le message
    Il me vient hypothèse en tête : il y aurait un UB qui dirait "tu ne peux pas faire de return dans une fonction s'il y a une boucle infinie". Si tel est le cas, ça expliquerait une différence de comportement entre C et C++ (en admettant que l'UB soit présent dans les 2 langages). Ca expliquerait que le comportement en C avec optimisation n'est pas celui attendu.
    C'est tout à fait ça :
    Memory model - Progress guarantee

    In a valid C++ program, every thread eventually does one of the following:
    • terminate
    • makes a call to an I/O library function
    • reads or modifies a volatile object
    • performs an atomic operation or a synchronization operation


    No thread of execution can execute forever without performing any of these observable behaviors.

    Note that it means that a program with endless recursion or endless loop (whether implemented as a for-statement or by looping goto or otherwise) has undefined behavior.
    Et démontré avec un code proche du code montré dans Undefined behavior - Infinite loop without side-effects.

    Suivant la complexité du code / l'optimisation demandée, si le compilateur parvient à détecter que la boucle ne se terminera jamais, alors il laissera libre court à son imagination.

  5. #25
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Mon pauvre... Si tu savais le nombre de code qui reposent sur des UB...
    Je suis content de ne pas le savoir

    Citation Envoyé par Winjerome Voir le message
    C'est tout à fait ça :

    Et démontré avec un code proche du code montré dans Undefined behavior - Infinite loop without side-effects.
    Tiens, j'ai appris quelque chose. Mais cela ouvre plein de questions. Par exemple un serveur dont le mécanisme général c'est "boucle infinie et dès qu'un client arrive je lance un fork pour traiter avec lui tandis que je retourne dans ma boucle" est-il dans ce cas en UB ???
    Accessoirement tes exemples et assertions parlent de C++ et ici on est en C. J'ai idée que cela ne changera pas grand chose mais fallait le préciser...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #26
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Par exemple un serveur dont le mécanisme général c'est "boucle infinie et dès qu'un client arrive je lance un fork pour traiter avec lui tandis que je retourne dans ma boucle" est-il dans ce cas en UB ???
    Non parce que le serveur finit par appeler le fork ou autre fonction, si un client arrive, chose externe au programme que le compilateur ne peut pas exclure.
    Ce n'est pas une boucle vide.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #27
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Accessoirement tes exemples et assertions parlent de C++ et ici on est en C. J'ai idée que cela ne changera pas grand chose mais fallait le préciser...
    Ça l'est, au début de la citation.
    Il n'y certes pas les mêmes lignes dans la partie C correspondante, mais on peut par contre y retrouver le même exemple. Niveau norme C, on peut lire :
    6.8.5 Iteration statements

    6. An iteration statement may be assumed by the implementation to terminate if its controlling expression is not a constant expression,(1)) and none of the following operations are performed in its body, controlling expression or (in the case of a for statement) its expression-3:(2))
    • input/output operations
    • accessing a volatile object
    • synchronization or atomic operations


    (1) An omitted controlling expression is replaced by a nonzero constant, which is a constant expression
    (2) This is intended to allow compiler transformations such as removal of empty loops even when termination cannot be proven.
    Ce qui restreint ainsi en C ce comportement à des boucles dont la condition n'est pas une expression constante. (De part le (1), for(;;) est considéré comme expression constante.)
    Citation Envoyé par Sve@r Voir le message
    Tiens, j'ai appris quelque chose. Mais cela ouvre plein de questions. Par exemple un serveur dont le mécanisme général c'est "boucle infinie et dès qu'un client arrive je lance un fork pour traiter avec lui tandis que je retourne dans ma boucle" est-il dans ce cas en UB ???
    C'est l'absence d'effet de bord (cf. liste ci-dessus) au sein de la boucle. J'ose espérer que les serveurs effectuent de nombreuses opérations avec effets de bord en leur sein, en particulier des traitements I/O dont fait partie le fork.
    Aucune raison donc de s'inquiéter .
    Dernière modification par Invité ; 29/11/2021 à 22h37.

  8. #28
    Membre expérimenté
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juillet 2020
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juillet 2020
    Messages : 352
    Points : 1 376
    Points
    1 376
    Par défaut
    Il n'y a aucun UB en C concernant les boucles infinies (may ≠ shall).

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. comment construire une boucle infinie sans bug
    Par stuffy dans le forum Général Python
    Réponses: 1
    Dernier message: 07/07/2008, 18h53
  2. Réponses: 15
    Dernier message: 24/05/2005, 08h34
  3. [Socket] Pb de boucle infinie
    Par Myogtha dans le forum Entrée/Sortie
    Réponses: 12
    Dernier message: 10/06/2004, 14h10
  4. [C#] Comment eviter les boucles infinies ?
    Par Thomas Lebrun dans le forum C#
    Réponses: 12
    Dernier message: 09/06/2004, 00h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo