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 :

[Pointeurs]Retour de fonctions - Warning inexpliqué


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut [Pointeurs]Retour de fonctions - Warning inexpliqué
    Bonjour. Ma question en fait se résume à "qu'est ce qui provoque l'avertissement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    main.c:9: warning: assignment makes pointer from integer without a cast
    et comme s'en prémunir ?"
    Merci beaucoup de m'aider à éliminer cet avertissement, car je le rencontre souvent et je voudrai bien m'en débarrasser.
    Mon code en fait est une fonction qui crée un tableau dynamiquement avec comme argument un entier size, la taille du tableau, et le type de retour est un pointeur sur entier, donc pour le tableau d'entier de retour de la fonction :
    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
    #include <stdlib.h>
    #include <time.h>
    #include <stdio.h>
     
    int * mkTablAlea(int size)
      {
      int i;
      int * Tableau;
      srand(time(NULL));
      if( ( Tableau=malloc(sizeof(int)*size) ) )
        {
        for (i=0;i<size;i++)
          *(Tableau+i)=rand();
        }
      else
        printf("\nerreur d'allocation sur mkTabAlea.c");
      return Tableau;
      }
    Le main.c se résume à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdlib.h>
    #include <stdio.h>
     
    #define sizeTab 20
     
    int main(void)
      {
      int * Tableau1;
      Tableau1 = mkTablAlea(sizeTab);
      afficheTableau(Tableau1,sizeTab);
      delElement(Tableau1,10,sizeTab);
      afficheTableau(Tableau1,sizeTab);
      return 0;
      }

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kromartien
    Bonjour. Ma question en fait se résume à "qu'est ce qui provoque l'avertissement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    main.c:9: warning: assignment makes pointer from integer without a cast
    et comme s'en prémunir ?"
    Tu ne comprends pas l'anglais ? C'est quand tu essayes de mettre la valeur d'un entier dans un pointeur.

    C'est techniquement faisable en C, mais ça dépend de l'implémentation (ici, gcc demande de mettre un typecast). Ou alors, c'est une erreur de codage (c'est souvent le cas).

    Cas typique d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main (void)
    {
       char *p = malloc (123);
     
       return 0;
    }
    malloc() n'est pas déclaré, donc le compilateur considère qu'il retourne un int. Evidemment, un int dans un char *, ça coince... (comportement indéfini -> BUG !)

    Mauvaise correction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main (void)
    {
       char *p = (char *) malloc (123);
     
       return 0;
    }
    On a rien changé, et on a toujours un int (16-bit, par exemple) qui rentre dans un char* (32-bit, par exemple), mais sans rien dire. (comportement indéfini -> BUG !)

    Bonne correction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #include <stdlib.h>
     
    int main (void)
    {
       char *p = malloc (123);
     
       return 0;
    }
    On a fourni un prototype au compilateur. Celui-ci sait maintenant que malloc() retourne un void* qui est compatible avec un char *. (et n'importe quel type 'pointeur sur objet').
    Merci beaucoup de m'aider à éliminer cet avertissement, car je le rencontre souvent et je voudrai bien m'en débarrasser.
    C'est extrêmement grave. Ca révèle des bugs dans ton code. Ca ne devrait jamais arriver.

    Mon code en fait est une fonction qui crée un tableau dynamiquement avec comme argument un entier size, la taille du tableau, et le type de retour est un pointeur sur entier, donc pour le tableau d'entier de retour de la fonction :
    Ce sont 2 fichiers séparés ? Il est où le header avec le prototype des fonctions ?

    Parce que là, on est dans un cas typique tel que je l'ai décrit plus haut... "absence de prototype" : c'est le type de retour 'int' qui est pris par défaut, d'où le warning. Il faut apprendre la programmation modulaire. Ceci peut aider :

    http://emmanuel-delahaye.developpez....ganiser_source
    http://emmanuel-delahaye.developpez.....htm#organiser

    pose des questions si tu ne comprends pas.

    Et aussi, mieux régler ton compilateur :

    http://emmanuel-delahaye.developpez....tm#cfg_compilo

    tu seras prévenu si il manque des prototypes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Project   : Forums
    Compiler  : GNU GCC Compiler (called directly)
    Directory : C:\dev\forums\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main.c
    main.c: In function `main':
    main.c:8: warning: implicit declaration of function `mkTablAlea'
    main.c:8: warning: assignment makes pointer from integer without a cast
    Linking console executable: console.exe
    Process terminated with status 0 (0 minutes, 1 seconds)
    0 errors, 2 warnings

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Merci beaucoup. Je n'avais pas construit le fichier d'en tête. Merci beaucoup. voilà le code au complet, si des choses sont mauvaises encore. :
    afficheTableau.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdlib.h>
    #include <stdio.h>
     
    void afficheTableau(int * tableau, int SizeTableau)
      {
      int i;printf("\n");
      for (i=0;i<SizeTableau;i++)
        {
        printf("tab[%d] = %d\n",i,tableau[i]);
        }
      }
    mkTablAlea.c
    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
     
    #include <stdlib.h>
    #include <time.h>
    #include <stdio.h>
     
    int * mkTablAlea(int size)
      {
      int i;
      int * Tableau;
      srand(time(NULL));
      if( ( Tableau=malloc(sizeof(int)*size) ) )
        {
        for (i=0;i<size;i++)
          *(Tableau+i)=rand();
        }
      else
        printf("\nerreur d'allocation sur mkTabAlea.c");
      return Tableau;
      }
    delElement.c
    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
     
    #include <stdlib.h>
     
    void delElement(int * tableau, int indice, int SizeTableau)
      {
      int temp;
      while(indice<SizeTableau-1)
        {
        temp=*(tableau+indice+1) ;
     
        *(tableau+indice+1)=*(tableau+indice) ;
     
        *(tableau+indice)=temp ;
     
        indice = indice + 1 ;
        }
      }
    MANIPTAB.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #ifndef H_DK_MANIPTAB_20070429
    #define H_DK_MANIPTAB_20070429
     
    void delElement(int*, int, int);
     
    int * mkTablAlea(int);
     
    void afficheTab(int *, int);
     
    #endif
    main.c
    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
     
    #include <stdlib.h>
    #include <stdio.h>
     
    #include "MANIPTAB.h"
     
    #define sizeTab 20
     
    int main(void)
      {
      int* Tableau1;
      Tableau1 = mkTablAlea(sizeTab);
      afficheTableau(Tableau1,sizeTab);
      delElement(Tableau1,10,sizeTab);
      printf("\n\n");
      afficheTableau(Tableau1,sizeTab);
      return 0;
      }

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kromartien
    Merci beaucoup. Je n'avais pas construit le fichier d'en tête. Merci beaucoup. voilà le code au complet, si des choses sont mauvaises encore. :
    C'est mieux, mais pourquoi un fichier par fonction ? En général, on fait le découpage en fonction des données à traiter. Ici, le tableau d'entier.

    Ca donne :

    * application :
    - main.c
    * fonctions de traitement du tableau
    - tab.h (interface)
    - tab.c (implémentation)

    Ensuite il est fortement recommandé (comme indiqué dans mes articles), d'inclure le header (.h) dans l'implémentation, afin de garantir "l'alignement" entre l'interface et l'implémentation.
    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
    21
    22
     
    /* main.c */
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
     
    #include "tab.h"
     
    #define sizeTab 20
     
    int main (void)
    {
       srand (time (NULL));
       {
          int *Tableau1 = tab_mk_alea (sizeTab);
          tab_affiche (Tableau1, sizeTab);
          tab_del_element (Tableau1, 10, sizeTab);
          printf ("\n\n");
          tab_affiche (Tableau1, sizeTab);
       }
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    /* tab.h */
    #ifndef H_DK_TAB_20070429
    #define H_DK_TAB_20070429
     
    void tab_affiche (int *tableau, int size);
    int *tab_mk_alea (int size);
    void tab_del_element (int *tableau, int indice, int size);
     
    #endif
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    /* tab.c */
    /* toujours en 1er dans l'implementation. */
    #include "tab.h"
     
    #include <stdlib.h>
    #include <stdio.h>
     
    void tab_affiche (int *tableau, int size)
    {
       int i;
       printf ("\n");
       for (i = 0; i < size; i++)
       {
          printf ("tab[%d] = %d\n", i, tableau[i]);
       }
    }
     
    int *tab_mk_alea (int size)
    {
       int i;
       int *Tableau = malloc (sizeof (int) * size);
       if (Tableau != NULL)
       {
          for (i = 0; i < size; i++)
          {
             *(Tableau + i) = rand ();
          }
       }
       else
          printf ("\nerreur d'allocation sur mkTabAlea.c");
       return Tableau;
    }
     
    void tab_del_element (int *tableau, int indice, int size)
    {
       int temp;
       while (indice < size - 1)
       {
          temp = *(tableau + indice + 1);
     
          *(tableau + indice + 1) = *(tableau + indice);
     
          *(tableau + indice) = temp;
     
          indice = indice + 1;
       }
    }
    J'ai déplacé srand()...

    http://emmanuel-delahaye.developpez.com/notes.htm#rand

    J'ai remanié un peu le nommage pour le rendre homogène autour de l'objet 'tab' (c'est un peu vague, mais ici, ça suffit).

    On pourrait un peu plus 'souder' les données en utilisant une structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct tab
    {
        int *tableau;
        int size;
    };
    Tu as le droit, même avec les pointeurs, d'utiliser la notation tableau ([]).

    Je te laisse mettre le code au point.

    N'oublie pas de libérer ce qui a été alloué...

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

Discussions similaires

  1. Retour de fonction pour allocation pointeur
    Par Tenshock dans le forum C
    Réponses: 8
    Dernier message: 26/12/2014, 21h44
  2. Réponses: 11
    Dernier message: 25/03/2008, 23h12
  3. Réponses: 11
    Dernier message: 07/01/2008, 19h47
  4. Réponses: 8
    Dernier message: 14/12/2007, 17h12
  5. retour de pointeur par une fonction
    Par Miko95 dans le forum C++
    Réponses: 17
    Dernier message: 12/12/2007, 01h33

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