Partage
  • Partager sur Facebook
  • Partager sur Twitter

Listons les messages courants de GCC

J'ai besoin de vous pour rédiger un tuto

    12 août 2011 à 17:53:31

    Bonjour tout le monde ! :)

    Je poste ce topic aujourd'hui car j'ai besoin de votre aide.
    Je suis en train de dresser la liste des messages d'erreur & warnings les plus courants de GCC.

    L'idée est de rédiger un petit tutoriel qui explique comment corriger soi-même les erreurs dans son code. Étant donné qu'il sera destiné aux visiteurs de ce forum, je suis curieux de voir quels sont les messages que vous rencontrez le plus fréquemment. Ce topic s'adresse donc tant aux contributeurs, qui aident à résoudre les problèmes, qu'aux questionneurs, qui débutent en langage C.

    J'aimerais, autant que possible, que vous postiez un message, un code minimal qui permet de le reproduire, et une petite explication si le message n'est pas clair.

    Veillez à vous restreindre aux messages fréquents (= que plusieurs personnes ici ont eues).

    Je vous remercie par avance pour vos contributions et vous souhaite une excellente journée ! :)
    GuilOooo

    PS : Les warnings obtenus à l'aide d'options supplémentaires (-Wall, -Wextra) sont bienvenus, du moment qu'ils embêtent les zéros !
    • Partager sur Facebook
    • Partager sur Twitter
    J'ai déménagé sur Zeste de savoir — Ex-manager des modérateurs.
      12 août 2011 à 18:19:04

      Salut,

      Bonne initiative :)
      Pour le moment, trois me viennent à l'esprit:

      warning: comparison between signed and unsigned integer expressions


      code minimal pour le reproduire:


      #include <stdio.h>
      #include <stdlib.h>
      
      
      int
      main(void)
      {
      	if (-1 < 10u)
      		puts("ok");
      	else
      		puts("oO");
      
      	return EXIT_SUCCESS;
      }
      



      explication: vous comparez un nombre signé avec un nombre non signé. Dans le cas où vous êtes certains que votre nombre signé ne sera jamais négatif, cela ne pose pas de problème. À l'inverse, si ce dernier est négatif, il sera converti en nombre non signé avant la comparaison, ce qui explique pourquoi la comparaison du code d'exemple est fausse.

      warning: implicit declaration of function ‘****’


      code minimal pour le reproduire:


      main.c




      #include <stdio.h>
      #include <stdlib.h>
      
      
      int
      main(void)
      {
      	printf("%lf\n", test());
      	return EXIT_SUCCESS;
      }
      




      test.c




      double
      test(void)
      {
      	return 0.5;
      }
      



      explications: signifie que vous utilisez une fonction qui n'a pas été déclarée. Dans un tel cas, le compilateur considère que cet fonction retourne un int et reçoit des arguments de type int (ou double suivant le type des arguments passés). Dans le code d'exemple, la fonction test sera considérée comme retournant un int, ce qui vous vaudra un avertissement de gcc (mauvais format de printf) et un affiche invalide.

      undefined reference to `****'



      #include <stdlib.h>
      
      
      void affiche(char const *s);
      
      
      int
      main(void)
      {
      	affiche("hello");
      	return EXIT_SUCCESS;
      }
      



      explication: signifie que l'éditeur de lien n'a pas trouvé le corps de votre fonction (ce qu'il y a entre accollades). Soit vous avez oublié de le fournir, soit un de vos fichiers n'a pas été correctement ajouté à votre projet.
      • Partager sur Facebook
      • Partager sur Twitter
        12 août 2011 à 18:25:05

        Merci pour tes idées !

        Les étourderies sur lesquelles je tombe souvent :

        error: redefinition of ***


        Code :

        #include <stdio.h>
        
        int main(void)
        {
            int i = 1;
            int i = 0;
            printf("%d\n", i);
            return 0;
        }
        


        Explications :

        Vous avez déclaré deux fois une même fonction ou une même variable.

        error: ‘***’ undeclared (first use in this function)
        error: (Each undeclared identifier is reported only once
        error: for each function it appears in.)


        Code :

        #include <stdio.h>
        
        int main(void)
        {
            printf("%d\n", i);
            return 0;
        }
        


        Explications : vous avez utilisé une variable sans la déclarer auparavant.
        • Partager sur Facebook
        • Partager sur Twitter
        J'ai déménagé sur Zeste de savoir — Ex-manager des modérateurs.
          12 août 2011 à 18:43:19

          Autre joyeuseté avec les unsigned. :)

          Il faut compiler avec l'option -Wextra pour avoir ce warning.
          warning: comparison of unsigned expression >= 0 is always true|

          #include <stdio.h>
          
          int main(void)
          {
              unsigned i; /* unsigned -> unsigned int */
              for(i = 5; i >= 0; i--)
                  printf("%u\n", i);
          
              return 0;
          }
          


          Explications
          Par défintion un unsigned ne sera jamais négatif.
          Dans la boucle de ce code par exemple, après 0, i prendra la valeur UINT_MAX, et c'est donc une jolie boucle infinie.
          • Partager sur Facebook
          • Partager sur Twitter
          Zeste de Savoir, le site qui en a dans le citron !
            12 août 2011 à 18:48:50

            Un truc relativement courant:
            error: expected ‘;’ before ‘return’


            Code minimal:
            #include <stdio.h>
            #include <stdlib.h>
            
            int main()
            {
                printf("HelloWorld !\n")
                
                return 0;
            }
            


            Explications:

            Vous avez oublié un ';' avant 'return'

            Voilà une autre:
            warning: unused variable ‘*’


            Code minimal:
            #include <stdio.h>
            #include <stdlib.h>
            
            int main()
            {
                int i = 0;
                printf("HelloWorld !\n");
                
                return 0;
            }
            


            Explications:

            Votre variable est inutilisée dans la fonction.

            Et une dernière
            warning: ‘*’ is used uninitialized in this function


            Code minimal:
            #include <stdio.h>
            #include <stdlib.h>
            
            int main()
            {
                int i;
                printf("%d\n", i);
                
                return 0;
            }
            


            Explications:

            Vous utilisez une variable non initialisée.

            Un dernier pour la route:
            warning: suggest braces around empty body in an ‘if’ statement


            Code minimal:
            #include <stdio.h>
            #include <stdlib.h>
            
            int main()
            {
                int i = 0;
                
                if(i < 0);
                {
                    printf("Helloworld !\n");
                }
                
                return 0;
            }
            


            Explications:

            Vous avez placez un ; après un if, cette condition sera donc toujours vraie.
            • Partager sur Facebook
            • Partager sur Twitter
              12 août 2011 à 19:02:14

              Salut,

              OK pour les warnings avec -Wall, -Wextra, ou autres joyeusetés.

              Toutes ces erreurs se rencontrent régulièrement sur le forum ?

              Je pensais qu'on aurait des trucs plus tordus, à base de conversion pointeur entier (Warning : conversion of pointer to integer without a cast), mais ça n'a pas l'air d'être la bête noire des visiteurs de ce forum.
              • Partager sur Facebook
              • Partager sur Twitter
              J'ai déménagé sur Zeste de savoir — Ex-manager des modérateurs.
                12 août 2011 à 19:22:20

                Salut,

                il arrive parfois qu'on rencontre aussi:

                error: expected declaration or statement at end of input


                Code minimal:

                #include <stdio.h>
                
                int function(void)
                {
                   printf("\nQuitter !\n");
                
                int main(void)
                {
                   function();
                   return 0;
                }
                


                Explication Vous avez oublié une accolade fermante quelque part. Assurer que chaque à chaque accolade ouverte correspond une fermée.
                • Partager sur Facebook
                • Partager sur Twitter
                  12 août 2011 à 19:44:37

                  Un tuto ? ça n'entre pas dans la catégorie 'trics & tips' ? :-°
                  Pour moi si. :-°
                  • Partager sur Facebook
                  • Partager sur Twitter
                    12 août 2011 à 19:53:47

                    Mais qui te dit que le tuto ne va parler que des messages d'erreur de GCC ? Corriger ses erreurs est un sujet vaste, qui peut aller d'un bon report des erreurs d'exécution à l'utilisation du débogueur. Il y a largement matière à faire un cours complet, et non une énumérations d'erreurs/correction.

                    Là, je recueille des données brutes. Ensuite, il faudra évidemment choisir, classer, expliquer, intégrer. Je ne suis pas fou au point de copier/coller ce topic tel quel dans un tuto, je connais les jaunes. ^^
                    • Partager sur Facebook
                    • Partager sur Twitter
                    J'ai déménagé sur Zeste de savoir — Ex-manager des modérateurs.
                      12 août 2011 à 19:54:50

                      Mouais, w8 & see... :-°

                      Aller, histoire de pas avoir posté pour rien :

                      main.c: In function ‘int main()’:
                      main.c:7: error: invalid conversion from ‘void*’ to ‘int*’


                      #include <stdio.h>
                      #include <stdlib.h>
                      
                      int main(void) {
                        int * tab;
                        
                        tab = malloc(5 * sizeof *tab);
                        
                        free(tab);
                        return EXIT_SUCCESS;
                      }
                      


                      Vous compilez en C++...

                      On peut aussi citer la somptueuse erreur du Mario Sokoban (d'une qualité incommensurable...) où ce cher mateo ne consent toujours pas à mettre un avertissement sur son somptueux tutoriel sur la SDL :

                      undefined reference to `editeur(SDL_Surface*)'
                      undefined reference to `jouer(SDL_Surface*)'
                      • Partager sur Facebook
                      • Partager sur Twitter
                        12 août 2011 à 22:04:40

                        Citation : GuilOooo

                        Je pensais qu'on aurait des trucs plus tordus, à base de conversion pointeur entier (Warning : conversion of pointer to integer without a cast), mais ça n'a pas l'air d'être la bête noire des visiteurs de ce forum.


                        Oh, je l'ai eu souvent celle-là, mais j'ai toujours réussi à trouver sans poster. Mais je ne peux pas mettre d'exemple, je ne sais pas exactement à quoi elle correspond... :euh: (à part qu'elle a un lien avec un pointeur...)
                        • Partager sur Facebook
                        • Partager sur Twitter
                          12 août 2011 à 23:54:36

                          Un warning qui peut expliquer certaines erreurs de segmentation:

                          /* Une fonction susceptible de modifier la chaine passée en paramètre*/
                          void une_fonction (char *param);
                          
                          int
                          main (void)
                          {
                          	const char *chaine = "Salut !";
                          	
                          	une_fonction (chaine);
                          
                          	return 0;
                          }
                          


                          $ gcc toto.c -c -Wall
                          toto.c: In function ‘main’:
                          toto.c:9:2: attention : passing argument 1 of ‘une_fonction’ discards ‘const’ qualifier from pointer target type [enabled by default]
                          toto.c:2:6: note: expected ‘char *’ but argument is of type ‘const char *’
                          On a définit 'chaine' dans 'main' comme étant de type constante, donc non modifiable. Seulement, 'une_fonction' prend en paramètre une chaine de caractère non-constante qui est donc susceptible d'être modifiée dans le corps de la fonction, et on envoie 'chaine' en paramètre à 'une_fonction'. Le compilateur nous avertit donc de cette pratique dangereuse en nous disant qu'on rejette le qualificatif 'const' de 'chaine' en le passant en paramètre à 'une_fonction'.

                          Dans le cas présent, on a de fortes chances d'avoir une erreur de segmentation à l’exécution.
                          • Partager sur Facebook
                          • Partager sur Twitter
                          - Il y a un chemin vers chaque sommet, même le plus haut -
                            13 août 2011 à 0:11:47

                            Citation : Nonolaclochette


                            Oh, je l'ai eu souvent celle-là, mais j'ai toujours réussi à trouver sans poster. Mais je ne peux pas mettre d'exemple, je ne sais pas exactement à quoi elle correspond... :euh: (à part qu'elle a un lien avec un pointeur...)



                            Comme ça par exemple:
                            #include <stdio.h>
                            #include <stdlib.h>
                            
                            int main()
                            {
                                int* nombre = NULL;
                                
                                nombre = 5;
                                
                                return 0;
                            }
                            
                            • Partager sur Facebook
                            • Partager sur Twitter
                              13 août 2011 à 11:31:19

                              Une erreur super courante :
                              erreur: expected ‘;’, identifier or ‘(’ before ‘*’
                              struct str 
                              {
                                 char chaine[50];
                              }
                              int main()
                              {
                                 
                                 return 0;
                              }
                              
                              • Partager sur Facebook
                              • Partager sur Twitter
                              🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.
                                13 août 2011 à 21:13:26

                                Citation : GuilOooo

                                Je pensais qu'on aurait des trucs plus tordus, à base de conversion pointeur entier (Warning : conversion of pointer to integer without a cast), mais ça n'a pas l'air d'être la bête noire des visiteurs de ce forum.


                                Je trouve que oui, c'est une erreur courante.

                                Sinon, il y a les erreurs d'initialisation, comme (approx) :
                                int array[2][5] = {0}
                                

                                warning : missing braces around initializer
                                bla bla bla...



                                Ou bien certaines moins classique (mais courantes chez les apprentis gourous :p ) :
                                a++ = 1
                                

                                error: lvalue required as left operand of assignment


                                a = a++
                                

                                warning : operation on * may be undefined
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  13 août 2011 à 21:27:17

                                  Citation : @che

                                  Une erreur super courante :
                                  erreur: expected ‘;’, identifier or ‘(’ before ‘*’

                                  struct str 
                                  {
                                     char chaine[50];
                                  }
                                  int main()
                                  {
                                     
                                     return 0;
                                  }
                                  


                                  C’est dans ces cas là que je suis content d’utiliser clang pour afficher les messages d’erreur. :)

                                  error: expected ';' after struct
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    13 août 2011 à 21:29:30

                                    Salut,

                                    Pour les deux dernières, j'en traite déjà dans le tuto, mais je ne connaissais pas les messages d'erreur associés ! Merci. :)

                                    Je prend note de toutes vos contributions. Merci à tous !

                                    PS : Au sujet de clang, j'y ai songé, les messages d'erreurs sont plus clairs. Mais ça représenterait un gros travail supplémentaire, et pour le coup, on virerait un peu au TEA. Mais je note l'idée : Clang est-il simple à installer avec Code::Blocks ?
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    J'ai déménagé sur Zeste de savoir — Ex-manager des modérateurs.
                                      13 août 2011 à 21:42:38

                                      Hmm, je ne suis pas sûr que ce soit particulièrement facile à installer sous Windows. Ça l’est par contre sous Linux — en général du moins — et sous Mac OS X où il est fourni avec Xcode. Je ne pense pas que ce soit vraiment nécessaire de lister les warnings et erreurs de GCC et ceux de clang. Tu pourrais juste mentionner l’existence d’autres compilateurs et le fait que les messages de clang sont parfois plus faciles à comprendre.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        13 août 2011 à 21:46:48

                                        Je comptais dire : « pour les gros projets, vous pouvez garder un compilateur alternatif sous le coude pour tester », et Clang me paraissait un bon choix. Les gens qui compilent en ligne de commande n'auront pas de soucis, mais nous avons clairement une majorité de gens sous Windows avec Code::Blocks. Donc bon, tant pis.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        J'ai déménagé sur Zeste de savoir — Ex-manager des modérateurs.

                                        Listons les messages courants de GCC

                                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                        • Editeur
                                        • Markdown