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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Femme Profil pro
    Étudiant
    Inscrit en
    Juin 2021
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 24
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2021
    Messages : 8
    Par défaut bug clang boucle infinie
    alut à toutes et tous

    j'ai un code qui fonctione en debug mais pas en optimisé et uniquement avec clang pas avec gcc. je voulais savoir votre avis si c'est un bug ou si c'est normal ou je sais pas. j'ai fait un code minimal pour vous faire la demo.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    #include <stdio.h>
     
    int test()
    {
        while(1)
        {
            for(int i=10; i<100; i++)
                if ( i*i > i*i*i )
                    return 1;
        }
        return 0;
    }
     
    int main()
    {
        printf("On test : ");
        if (test()) printf("VRAI\n");
        else        printf("FAUX\n");
    }
    comme un carré est toujours plus petit qu'un cube si c'est plus grand que 10 je dois jamais sortir du while et ca doit tourné en rond. c'est ce que ça fait avec clang en mode debug mais si je demande un O3 alors ça plante plus et ça m'affiche vrai.

    je compile avec clang comme ça

    clang -Werror -Wall -Wextra -O3 -o simple_clang_O3 simple.c et clang -Werror -Wall -Wextra -g -o simple_clang_g simple.c

    j'ai pas de message et si je lance simple_clang_O3 il m'affiche On test : VRAI et il m'affiche rien avec l'autre et s'arrête pas.

    ca le fait pas avec gcc.

    vous avez des idées ? le O3 de clang est cassé et je dois plus l'utilisé ou je passe avec gcc qui est plus sure ?

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    gcc optimise surement en laissant le while infini tandis que clang le vire puisqu'il est vide.
    Il faut comparer le code généré.
    L'erreur c'est surtout ce code. Mais il devrait afficher faux imo.
    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.

  3. #3
    Membre habitué
    Femme Profil pro
    Étudiant
    Inscrit en
    Juin 2021
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 24
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2021
    Messages : 8
    Par défaut
    le code c'est une demo minimaliste. je vais pas copier tout le code que j'ai. ça fait que reproduire une erreur.
    alors non c'est une boucle infinie donc ça doit boucler. le comportement est ok sans O3 mais avec O3 ça donne un programme qui fait pas le code. pour moi c'est un bug.

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Le problème est reproductible sur Compiler Explorer avec les dernières versions de chaque compilateur : https://godbolt.org/z/63G7Pe5GY

    Une versions sans printf() est plus simple si on souhaite analyser l'assembleur pour comprendre ce qu'il se passe (je n'ai pas fait cet effort):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    int test()
    {
        while(1)
        {
            for(int i=10; i<100; i++)
                if ( i*i > i*i*i )
                    return 1;
        }
        return 0;
    }
     
    int main()
    {
        return test();
    }
    Le problème ne semble pas venir d'O3 en lui-même : ça semble tourner en rond de la même manière quelque soit le niveau d'optimisation. Du coup je me demande si ça se passe bien quand on compile qq chose avec GCC sur Compiler Explorer. --> j'ai essayé avec fonction test() qui fait un simple return 0; et ça compile et s'exécute correctement. Ca vient donc bien de ton sample, dans lequel je ne vois pas de problème.

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    L'analyse qui est peut-être faite par l'optimiseur:
    - Il n'y a aucun effet de de bord dans la fonction
    - toutes les données sont des constantes
    - donc il y a une solution qui peut entièrement se résoudre à la compilation
    - la fonction s'engage à retourner un entier, 2 possibilités dans le code : retourner 0 ou retourner 1.
    - ça ne peut pas être 0 car il est après un while sans sortie.
    - seule possibilité : la fonction doit retourner 1.
    Le seul détail oublié c'est qu'il faut un temps infini avant de retourner 1. Mais pourtant cette fonction ne peut que retourner 1.

  6. #6
    Membre chevronné
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Septembre 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Septembre 2015
    Messages : 213
    Par défaut
    pour le code généré, vous pouvez regarder sur le site suivant : https://godbolt.org/

    on voit bien que pour clang, il transforme la méthode en return 1 !

    alors qu'avec gcc, on ne voit pas le return 0; mais on "voit" la boucle sans fin

  7. #7
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    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 226
    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".

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    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.

+ Répondre à la discussion
Cette discussion est résolue.

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