Forum Programmation.c Compiler un ancien outil écrit en C sous gcc

Posté par  .
0
14
nov.
2006
Salut,

J'ai essayé de compiler un ancien outil écrit en C (du type Kernighan & Ritchie), sur un Redhat Enterprise 4, avec un gcc 3.4.6, mais j'ai eu des erreurs du genre types incompatibles concernant la fonction malloc et calloc.
En regardant, j'ai vu que le code de l'outil utilise la fonction char* malloc, alors que la malloc définie dans la Redhat retourne Void.

J'ai cherché une option de gcc qui permet de compiler en supposant les anciennes versions du C standard (de Kernighan Ritchie), mais je n'ai pas trouvé !

Qq'un a-t-il une solution pour moi ?

Merci beauc,
Nabila
  • # C iso

    Posté par  (site web personnel) . Évalué à 2.

    Essaye de compiler avec l'(es) option(s) :

    -ansi (-std)

    Pour forcer l'utilisation du C iso ...
    • [^] # Re: C iso

      Posté par  . Évalué à 1.

      Merci, mais j'ai essayé avec cette option, toujours les mêmes types d'erreur !

      N' y a-t-il pas autre solution ?

      Merci,
      Nabila
  • # Glibc

    Posté par  (site web personnel) . Évalué à 6.

    Je crois que ton problème ne vient pas de gcc mais de la glibc. En effet, c'est elle qui fournie la déclaration de malloc et cmalloc (cf. /usr/include/stdlib.h).

    Je pense que tu n'as pas d'autre choix que de passer par un "cast" :
    char *toto = (char*) malloc(.....*sizeof(char));

    Eventuellement, tu peux te faire de la méta-programmation avec une macro :
    #define MALLOC(type, taille) (type *) malloc((taille)*sizeof(type));
    • [^] # Re: Glibc

      Posté par  . Évalué à 8.

      Le cast est inutile, et ton exemple n'est pas approprié. Si la libc de son système déclare *alloc comme retournant des valeurs de type void * (ce qui est correct en mode C90 et plus), alors le code:

      size_t n = /* untruc */ ;
      char * toto = malloc(n);

      marche très bien quand il est compilé en mode C90 ou plus (car la conversion implicite void * => char * est définie).

      Par ailleurs, note que sizeof(char) vaut toujours 1, par définition, et donc qu'on peut l'oublier dans l'écriture de l'argument à *alloc() (sauf si on veut insister explicitement).

      Le problème, c'est que le malloc du C K&R renvoie une valeur de type char *, et donc que, quand on avait besoin d'une valeur de type T*, où T est un type incompatible avec char (come un int, une structure, ou un truc bizarre), alors on pouvait écrire du code comme

      char *p1 = malloc(n * sizeof T);
      T *p2 = p1;

      ce qui était valide en C K&R, car la conversion implicite d'une valeur de type char * en tout autre type T * était définie (si je ne m'abuse), mais cette conversion cause un comportement indéfini en C90 (ou au mieux implementation-defined). A ma connaissance, gcc ne supporte *pas* de mode K&R, mais tolère juste certaines notations K&R quand on compile en mode "extentsion Gnu", donc un tel code risque de toujours lever des warnings dans gcc.

      Par aileurs, sans voir le code qui pose problème, il est difficile d'apporter une vraie solution au problème... Peut-être (et même probablement) est-il nécessaire de changer le code mais, sans le voir, c'est difficile à dire...
      • [^] # Re: Glibc

        Posté par  . Évalué à 1.

        Merci beaucoup pour ttes ces explicitations,
        Je suis tt à fait d'accord avec toi concernant les conversions implicites !

        J'ai essayé de suivre ton conseil de faire du cast là où la conversion implicite ne marche pas, mais, il ya beaucoup de fichiers à modifier !!!!

        D'après toi, pas de solution autre que de modifier le code qui cause les erreurs ?

        Merci quand même !
        A+
        Nabila
        • [^] # Re: Glibc

          Posté par  . Évalué à 1.

          Tu as deux solutions:

          1) trouver un compilo K&R. La portabilité serait minimale, et la mintenance douteuse. de plus, ça te prive des avancés du C depuis près d'une vingtaine d'années (1989, quand même)...

          2) corriger le code. Ca peut se faire de 2 façons:
          a) des casts pour faire taire le compilateur. C'est très rarement une bonne idée, car ça cache des comportements plus ou moins indéfinis, ce qui veut dire que ça peut ne pas marcher (enfin, ça cache les warnings, mais ça ne garantit pas que ton appli marche bien après).

          b) ou remplacer les char * par des void * à chaque fois que c'est possible. C'est la solution que je préfère. Par exemple, dans mon post précédent, il faudrait simplement ne pas passer par une variable temporaire char *p1 et affecter directement le retour de malloc dans p2, ou changer la déclaration du type de p1 de char * en void *.

          Mais une telle modification doit être faite avec attention, car il faut distinguer les cas où on a vraiment besoin du type char, pour traiter des chaînes de caractères, et où il est utilisé comme type "générique" (ce pour quoi le type void a été créé).

          Bref, bon courage.
          • [^] # Re: Glibc

            Posté par  . Évalué à 1.

            Merci pour tes 2 solutions :
            1) La solution (1) ne m'intéresse pas, car la machine sur laquelle j'installe est un serveur partagé entre plusieurs, donc je ne peux changer le compilo.

            2) J'ai essayé la solution (2a), c'est vrai que les erreurs ont disparu, j'ai eu beaucoup de warnings, mais l'outil ne marche pas bien comme tu dis : des parties marchent, et d'autres donnent des erreurs !

            La solution (2b) par contre est impossible à faire car l'outil est vraiment complexe (plein de calcul, de cas). Je ne peux me hazrder à le faire.

            Merci bien.
            • [^] # Re: Glibc

              Posté par  . Évalué à 1.

              Pour le 2a), j'ai bien dit que ça pouvait ne pas marcher. D'ailleurs, en C, les casts sont rarement bon signe (sauf cas rares comme en passage de paramètres à des fonctions à nombres de paramètres variables).

              Suivant la taille du machin, la correction (le 2b) du code pour le faire fonctionner en environnement C90 (ou même C99) peut être une opération lourde, je n'en doute pas. A toi de voir, suivant le temps dont du dispose, sur qui tu peux taper (ceux qui ont créé l'appli sont toujours dispo ?)...

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.