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 :

Fonction malloc en C


Sujet :

C

  1. #1
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Par défaut Fonction malloc en C
    Bonsoir,

    Ma question concerne la fonction malloc() en C et spécialement le type void* qu'elle retourne. J'ai appris par ailleurs qu'il n'était pas nécessaire de faire un cast du pointeur retourné. Est-ce vrai ? Si c'est le cas merci de m'indiquer la source.

    Merci par avance.

  2. #2
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    C'est dans la FAQ : Faut-il caster malloc ?

  3. #3
    Membre éprouvé Avatar de alexrtz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 639
    Par défaut
    Citation Envoyé par uknow Voir le message
    J'ai appris par ailleurs qu'il n'était pas nécessaire de faire un cast du pointeur retourné. Est-ce vrai ? Si c'est le cas merci de m'indiquer la source.
    C'est vrai, mais je trouve la réponse de la FAQ de dvp un poil trop catégorique.
    Perso je préfère cette réponse.

  4. #4
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Moi j'adhère par contre entièrement la réponse de la FAQ dvp.

    1. De l'inutilité : Les raisons les plus fréquentes qui poussent certains programmeurs à caster malloc sont :

    a. L'ignorance : "Je mets un cast comme ça c'est sûr que ça marche. Je m'en fiche que ça soit utile ou pas.".

    -> Jusqu'à quand programmer dans ces conditions ? Lorsqu'on sait que c'est inutile, il n'y a aucune raison soutenable de le mettre. C'est comme écrire :
    Bien sûr que ça marche. Mais le cast est inutile, donc à supprimer.

    b. La "C/C++"-mania : "En C++, le cast est requis donc vaut mieux toujours le mettre, même en C où ce n'est pas requis".

    -> Il y a peu (pour ne pas dire pas) d'intérêt à écrire du code compatible C et C++. Du code C, même 100% incompatible C++, peut toujours être compilé en C (bien sûr) ensuite utilisé dans du code C++. Pas besoin de programmer en langage spaghetti pour mixer ces deux langages.

    2. Du danger :

    Le cast force le compilateur à faire la conversion même lorsque le type retourné par malloc n'est pas void *. Si on a oublié d'inclure stdlib.h par exemple, le compilateur supposera que malloc est une fonction qui retourne un int. A cause du cast, le compilateur ne génèrera pas un avertissement du type "int converti en pointeur" or affecter le retour d'une fonction qui renvoie int à un pointeur est dangereux (imagine par exemple que la taille d'un int est différente de celle d'un pointeur, qu'est-ce qui va se passer !? or ce n'est pas que ça ...).

    Donc personnellement, je recommande vivement de ne jamais caster malloc lorsqu'on programme en C.

  5. #5
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    La plupart du temps les gens font des casts sur malloc parce qu'ils compilent en C++.
    Si ce n'est pas ça c'est parce qu'on leur à enseigné comme ça.

  6. #6
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Ce qui rejoint ce que j'ai dit. Selon toi :

    - Soit ils font volontairement du C/C++ (ce qui peut faire l'objet d'un débat : "Faire du C/C++ : est-ce bien ou mal ?"), ce qui rejoint mon 1.b.

    - Soit ils le font sans le savoir mais juste parce qu'on le leur a enseigné ainsi, ce qui rejoint mon 1.a. et dans ce cas, soit le prof lui-même ne connaît pas assez le C (croyez-moi, ça existe, j'ai vu de mes propres yeux et pas qu'une seule fois), soit c'est un prof qui n'a pas l'intention de tout enseigner à ses élèves (et ça aussi, ça existe).

  7. #7
    Membre éprouvé Avatar de alexrtz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 639
    Par défaut
    Citation Envoyé par Melem Voir le message
    Les raisons les plus fréquentes qui poussent certains programmeurs à caster malloc sont :

    a. L'ignorance : "Je mets un cast comme ça c'est sûr que ça marche. Je m'en fiche que ça soit utile ou pas.".

    (...)

    b. La "C/C++"-mania : "En C++, le cast est requis donc vaut mieux toujours le mettre, même en C où ce n'est pas requis".
    Perso c'est plutôt pour cette raison :
    On the other hand, some programmers prefer to make every conversion explicit, to record that they have considered each case and decided exactly what should happen
    Et comme je compile avec des options qui me si y a le moindre warning, je risque pas d'oublier un en-tête

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Melem Voir le message
    Moi j'adhère par contre entièrement la réponse de la FAQ dvp.
    ..
    Donc personnellement, je recommande vivement de ne jamais caster malloc lorsqu'on programme en C.
    Et personellement, et j'ai déjà eu l'occasion de le dire plusieurs fois, je suis contre cette "recommandation", pour 2 raisons..

    • a) l'argument du "danger" :

      ce danger n'existe que pour des programmeurs débutants. Il faudrait alors interdire toute utilisation "limite" de tout ce qui en C peut être mal interpété ou mal utilisé par un débutant.. ça fait beaucoup..


    • b) l'aspect documentaire / maintenance :

      le fait d'avoir des casts explicites dans le code non seulement permet à tout moment de la lecture de savoir à quel type on a affaire, mais également, en cas de modification du type d'un champ, de relever instantanément (erreur ou warning de compil) toute inconsistance entre pointeurs..



    Alors je suis effectivement beaucoup plus d'accord avec ce que dit comp.lang.c qu'avec une politique et une affirmation péremptoire de la "nocivité" de cette utilisation...

  9. #9
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Tout ceci est un troll énorme entre deux factions de la programmation C. Les gens pour le cast auront leurs raisons et les gens contre aussi.

    Je suis contre le cast puisque je compile avec des options de compilation strictes et parce que j'ai déjà eu un problème dû à ce cast.

    Jc

  10. #10
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    pour le troll, effectivement il semble assez velu..

    Néanmoins, je ne vois pas ce que viennent faire des options strictes dans ce débat..

    Je compile aussi avec des options strictes

  11. #11
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    a) l'argument du "danger" :

    ce danger n'existe que pour des programmeurs débutants.
    Oublier d'inclure un fichier d'en-tête n'est pas forcément une erreur de débutant bien que ça arrive le plus souvent, je l'admets, aux débutants. Dans cette réponse, j'ai confondu cstdlib (le stdlib.h de C++) avec cstring (le string.h de C++), d'où inclusion d'un fichier d'en-tête inutile et omission du bon fichier d'en-tête. Je connais au moins 3 raisons (tous des cas déjà vécus, aussi bien quand je débutais que depuis que je me suis amélioré) qui peuvent causer l'oubli d'un fichier d'en-tête :

    - Oubli pur et simple. Les oublis, ça peut arriver à tout le monde.

    - Confusion avec un autre fichier d'en-tête. On pense avoir inclus le fichier requis mais en fait on a inclus un autre, probablement un qui a un nom ou un rôle plus ou moins ressemblant ...

    - Erreur de jugement. Prends ceci par exemple (exemple vraiment très simple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* Fichier include1.h */
    #if condition
    ..
    #include <stdlib.h>
    ...
    #endif
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    /* Fichier source1.c */
    #include "include1.h"
    Ici aussi, dans source1.c, lorsqu'on pense que condition vaut VRAI, alors on pense avoir déjà inclus stdlib.h même s'il n'a pas effectivement été inclus. condition peut être une expression simple, complexe ou hypercomplexe. Faire des erreurs sur l'évaluation de sa valeur peut arriver à tout le monde, pas aux débutants uniquement.

    On peut tous croire que tu n'as jamais fait d'erreurs de ce genre et que tu n'en feras jamais mais malheureusement, tout le monde n'est pas aussi talentueux que toi. Comme je l'ai dit, toutes ces erreurs me sont déjà arrivées, et j'ai également vu d'autres personnes se faire avoir. C'est un fait, on peut ne pas en discuter.

    b) l'aspect documentaire / maintenance :

    le fait d'avoir des casts explicites dans le code non seulement permet à tout moment de la lecture de savoir à quel type on a affaire,
    Explique-moi alors pourquoi personne n'écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    long y;
    /* 1 kilomètre après */
    y = (long)1;
    Pour rappeler que y est un long ? Ce n'est pas pour rien que les conversions implicites existent. void * est compatible avec tous les types pointeurs d'objet. Ca ne rime vraiment rien de caster un void *.

    mais également, en cas de modification du type d'un champ, de relever instantanément (erreur ou warning de compil) toute inconsistance entre pointeurs.
    Si tu modifies un type, tu dois déjà modifier pas mal de choses dans le code source lui-même. Ca se limite rarement à ajouter ou modifier des casts ... (un peu (mais pas vraiment) hors-sujet : cf la signature de Médinoc ).

  12. #12
    Membre éprouvé Avatar de alexrtz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 639
    Par défaut
    Citation Envoyé par Melem Voir le message
    Ici aussi, dans source1.c, lorsqu'on pense que condition vaut VRAI, alors on pense avoir déjà inclus stdlib.h même s'il n'a pas effectivement été inclus. condition peut être une expression simple, complexe ou hypercomplexe. Faire des erreurs sur l'évaluation de sa valeur peut arriver à tout le monde, pas aux débutants uniquement.
    Le compilateur aussi ?

    Parce que si le fichier n'est pas inclus, la déclaration de malloc n'est pas explicite et alors là le compilo gueule (et arrête de compiler si les bonnes options sont settées).

    Au risque de radoter avec la FAQ de comp.lang.c :
    On the other hand, some programmers prefer to make every conversion explicit, to record that they have considered each case and decided exactly what should happen
    Caster un pointeur n'est pas une hérésie punissable du fouet, c'est juste un moyen pour les programmeurs qui savent que le cast n'est pas nécessaire mais qui trouvent que c'est plus lisible avec le cast (la notion de lisibilité étant parfois subjective) de clarifier (selon eux) ce qu'ils font.
    C'est tout.

    Les problèmes cités avec le cast n'existent pas si on regarde les warnings que sort le compilateur (ou qu'on les considère comme des erreurs) et qu'on ne se dit pas bêtement "j'ai eu un exécutable donc y a eu zéro souci à la compilation" (ça c'est clairement une erreur de débutant).

  13. #13
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Le compilateur aussi ?

    Parce que si le fichier n'est pas inclus, la déclaration de malloc n'est pas explicite et alors là le compilo gueule
    Pas tous. Avec gcc par exemple, l'option -W (enable standard compiler warnings), ni même l'option -pedantic (enable warning demanded by strict ISO C (en mode C90)), ne génère pas le message d'avertissement "implicit declaration". Il faut compiler avec les options les plus strictes possibles (-Wall) pour que ce message soit généré. Et déjà ça ce n'est que gcc, mais on ne va pas passer la soirée à étudier cas par cas les quelques milliers de compilateurs C existants. Je ne connais par contre pas de compilateur qui reste muet devant une conversion implicite d'entier vers pointeur ou de pointeur vers entier même sans options de compilation spéciales, parce que c'est souvent un peu louche.

    Caster un pointeur n'est pas une hérésie punissable du fouet, c'est juste un moyen pour les programmeurs qui savent que le cast n'est pas nécessaire mais qui trouvent que c'est plus lisible avec le cast (la notion de lisibilité étant parfois subjective) de clarifier (selon eux) ce qu'ils font.
    Au risque de me répéter (3ème fois !), pourquoi on n'écrit jamais long n = (long)1; ?! C'est du même cru que le char * p = (char *)malloc(...);. En quoi expliciter une conversion implicite qui n'a rien de louche améliorerait la lisibilité ? Au contraire, c'est gênant. Bon, je te rejoins quand tu dis que la notion de lisibilité est subjective mais là quand même ...

    Les problèmes cités avec le cast n'existent pas si on regarde les warnings que sort le compilateur (ou qu'on les considère comme des erreurs) et qu'on ne se dit pas bêtement "j'ai eu un exécutable donc y a eu zéro souci à la compilation" (ça c'est clairement une erreur de débutant).
    On dirait que tu essaies de répondre à ceci :
    Citation Envoyé par Melem
    Si tu modifies un type, tu dois déjà modifier pas mal de choses dans le code source lui-même. Ca se limite rarement à ajouter ou modifier des casts ...
    Mais ta phrase est très mal formulée. La mienne aussi apparemment. J'ai répondu, pour contrer souviron34, que lorsqu'on change un type dans un projet, ce n'est rarement en plantant ou en modifiant des casts qu'on va pouvoir mettre à jour le reste du code. Cela demande beaucoup de changements radicaux. Ceci pour conclure que son argument ne peut pas compter.

  14. #14
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Ceci est mon dernier message sur le sujet, je me suis déjà étendu longuement à ce propos ailleurs sur ce forum...


    Citation Envoyé par Melem Voir le message
    Dans cette réponse, j'ai confondu cstdlib (le stdlib.h de C++) avec cstring (le string.h de C++), d'où inclusion d'un fichier d'en-tête inutile et omission du bon fichier d'en-tête.
    Voilà ce que c'est de mélanger C et C++

    Moi je ne fais que du C, et, je ré-itère, je n'ai jamais eu ce cas, en tous cas pas méchamment : à la première compile, le compilo te jette, et si tu fais gaffe à ce qu'il dit, tu t'en rend compte instantanément..

    Ce n'est toujours pas une raison valable pour l'instaurer en Commandement...

    Une compile, sur un gros projet, tu en fais (en dev, sur ta cope du code) environ une fois toutes les 5 minutes, au plus 1 fois par heure...

    Compiler une fois et te rendre compte et corriger, par rapport à perturber des milliers de lignes, franchement pour moi ya pas photo...





    Citation Envoyé par Melem Voir le message
    Je connais au moins 3 raisons (tous des cas déjà vécus, aussi bien quand je débutais que depuis que je me suis amélioré) qui peuvent causer l'oubli d'un fichier d'en-tête :

    - Oubli pur et simple. Les oublis, ça peut arriver à tout le monde.

    - Confusion avec un autre fichier d'en-tête. On pense avoir inclus le fichier requis mais en fait on a inclus un autre, probablement un qui a un nom ou un rôle plus ou moins ressemblant ...
    Voir plus haut..

    Un compilo bien réglé et le fait de faire gaffe à la sortie du compilo t'averti dès le premier passage...



    Citation Envoyé par Melem Voir le message
    - Erreur de jugement. Prends ceci par exemple (exemple vraiment très simple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* Fichier include1.h */
    #if condition
    ..
    #include <stdlib.h>
    ...
    #endif
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    /* Fichier source1.c */
    #include "include1.h"
    Ici aussi, dans source1.c, lorsqu'on pense que condition vaut VRAI, alors on pense avoir déjà inclus stdlib.h même s'il n'a pas effectivement été inclus. condition peut être une expression simple, complexe ou hypercomplexe. Faire des erreurs sur l'évaluation de sa valeur peut arriver à tout le monde, pas aux débutants uniquement.
    Sauf que là c'est une erreur de conception...

    si le fichier source1 a besoin de stdlib.h, il faut l'inclure de toutes façons, sans intermédiaires.. Sauf (ce que je mentionnais dans un autre thread) sur les gros projets où on a un "CommonC.h" qui comprendra tous les entêtes généraux (stlib, stdio, time, ctype, string, math par exemple)..


    Je ne comprend vraiment pas cette façon de NE PAS vouloir inclure plusieurs fois des fichiers d'entête...

    Les #ifdef sont justement là pour vérifier qu'on ne les inclue pas inutilement.. Alors pourquoi se priver de mettre les include là où on a besoin ???

    Dans un cas comme le cas cité, si je n'ai pas de "CommonC.h", j'incluerais stdlib ET dans include1.h ET dans include.h ET dans source1.c...



    Citation Envoyé par Melem Voir le message
    On peut tous croire que tu n'as jamais fait d'erreurs de ce genre et que tu n'en feras jamais mais malheureusement, tout le monde n'est pas aussi talentueux que toi. Comme je l'ai dit, toutes ces erreurs me sont déjà arrivées, et j'ai également vu d'autres personnes se faire avoir. C'est un fait, on peut ne pas en discuter.
    J'en ai fait, comme tout le monde, mais comme je l'ai dit l'apparition des erreurs étant tellement évidente à la compile, je ne vois pas en quoi établir une règle aussi absurde et sans fondements réels serait une bonne chose : encore une fois, si on doit faire éviter les erreurs de C possibles, autant enlever les notions de pointeurs, de void, etc etc...

    Le C est un langage simultanément laxiste et rigoureux, pour des gens qui savent ce qu'ils font..

    Comme la langue française peut en même temps être simple et compliquée.. Est-ce pour autant une raison pour écrire en SMS ou ne pas appliquer les règles de grammaire ou d'accord féminin/masculin ???





    Citation Envoyé par Melem Voir le message
    Explique-moi alors pourquoi personne n'écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    long y;
    /* 1 kilomètre après */
    y = (long)1;
    Pour rappeler que y est un long ?
    Parce que là c'est un long, un type élémentaire d'une variable..

    Soit tu n'as jamais travaillé sur de très gros projets, ou bien tu ne veux pas voir : la plupart du temps, tu as des dizaines de pointeurs, dans des structures, qui peuvent être des élements de listes, de tableaux, des structures, ce que tu veux, qui sont alloués par exemple à un endroit, puis réalloués à d'autres, éventuellement dans diverses fonctions, et libérés encore ailleurs..

    La définition de la structure n'est pas forcément proche : que ce soit la routine d'initialisation, d'allocation, de remplissage, de réallocation, de destruction... D'autre part cette structure peut contenir de nombreux pointeurs, chacun pointant sur de nouvelles structures... etc etc..


    Avoir tout sans cast explicite fait que tu te tortures l'esprit en relisant le code, savoir que tel sous-sous-sous pointeur sera (est ??) de tel ou tel type...


    ça m'arrive en permanence d'avoir des pointeurs de pointeurs de pointeurs de pointeurs... Chacun étant alloué dynamiquement..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DataSets[k].Source[j].Data[Num].Location[i].Altitude.Value.d
    Et encore ce n'est qu'un exemple simple...

    Dans les routines d'allocations ou des réallocation, cela sert d'aspect documentaire... Et cmme je le dit plus bas pour "tracker" un changement..




    Citation Envoyé par Melem Voir le message
    Ce n'est pas pour rien que les conversions implicites existent. void * est compatible avec tous les types pointeurs d'objet. Ca ne rime vraiment rien de caster un void *.
    Absolument.. Void* existe POUR POUVOIR PASSER UN PARAMETRE QUELCONQUE A UNE FONCTION....

    Son utilisation en tant que cast de résultat de fonction est vraiment d'un usage ultra-limité... :

    en fait il n'y a que le malloc, et si on veut stocker un pointeur sur quelque chose d'inconnu dans une structure..




    Citation Envoyé par Melem Voir le message
    Si tu modifies un type, tu dois déjà modifier pas mal de choses dans le code source lui-même. Ca se limite rarement à ajouter ou modifier des casts ... (un peu (mais pas vraiment) hors-sujet : cf la signature de Médinoc ).
    Sauf que justement, sans cast explicite, tu peux oublier tout un tas de trucs, en particulier dans les allocations ou réallocations..

    Un exemple très simple :

    devient

    Si d'une part tu n'as pas casté, et d'autre part tu as omis sizeof(char), alors tu es dans une grande panade, sur un très gros soft...

    C'est tout...



    Citation Envoyé par Melem Voir le message
    Pas tous. Avec gcc par exemple, l'option -W (enable standard compiler warnings), ni même l'option -pedantic (enable warning demanded by strict ISO C (en mode C90)), ne génère pas le message d'avertissement "implicit declaration". Il faut compiler avec les options les plus strictes possibles (-Wall) pour que ce message soit généré. Et déjà ça ce n'est que gcc, mais on ne va pas passer la soirée à étudier cas par cas les quelques milliers de compilateurs C existants.
    Comme je n'utlise aucun IDE, que je suis sous Unix/Linux, et que je compile toujours avec gcc en ligne de commande, et j'ai toujours -Wall -strict_prototypes -ansi (-ANSI90)..




    Citation Envoyé par Melem Voir le message
    Je ne connais par contre pas de compilateur qui reste muet devant une conversion implicite d'entier vers pointeur ou de pointeur vers entier même sans options de compilation spéciales, parce que c'est souvent un peu louche.
    si tu ne fais pas de conversion EXPLICITE, il suffit d'oublier -Wall et tu ne l'as pas...

    Les compilateurs ne restent pas muets, encore faut-il voir sortir les erreurs...



    Citation Envoyé par Melem Voir le message
    J'ai répondu, pour contrer souviron34, que lorsqu'on change un type dans un projet, ce n'est rarement en plantant ou en modifiant des casts qu'on va pouvoir mettre à jour le reste du code. Cela demande beaucoup de changements radicaux. Ceci pour conclure que son argument ne peut pas compter.
    C'est tout simplement faux...

    Reprend mon exemple plus haut..

    Un "gros" changement dans un projet n'est pas vraiment pas rapport au type, mais souvent de transfomer une valeur en un tableau, ou un tableau en une liste (et donc un pointeur) ou un tableau à plus de dimensions.

    Si on a casté, avec xemacs par exemple (et je suis sûr que c'est pareil avec les IDE classiques) tu fais "replace / toto = (char *) / toto = (char **) /" et il te positionnera sur toutes les lignes contenant ça et te demandera "remplacer ou non ?".. et tu auras beaucoup moins d'occurences (et donc de possibilités de se tromper) que si tu cherches "toto" ou même "toto ="...



    J'ai très rarement vu un changement de vrai type, ou alors c'est que la conception avait mal fait son boulot..



    Enfin, je ne m'étendrais plus là-dessus, mais je trouve plus qu'irritant la façon de vouloir inculquer comme le Grand Méchant Diable cette pratique..

    Et même de la déconseiller..

    Je dirais le mieux serait de dire : les 2 options sont possibles et se défendent..



    Mais, d'après tes premières remarques, c'est possible que ce soit parce que vous côtoyez trop C++ que vous pensiez ça.... Ou alors c'est peut-être l'usage des IDE, ou du C côté Windows..


    Je n'en ai jamais fait, ni des uns ni des autres, et moi, en C pur, je MAINTIENS QU'IL EST BIEN DE CASTER

  15. #15
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Sujet récurrent en effet... Juste une réaction sur un point :

    Citation Envoyé par Melem Voir le message
    -> Il y a peu (pour ne pas dire pas) d'intérêt à écrire du code compatible C et C++. Du code C, même 100% incompatible C++, peut toujours être compilé en C (bien sûr) ensuite utilisé dans du code C++. Pas besoin de programmer en langage spaghetti pour mixer ces deux langages.
    Il y en a pourtant, notamment sur les modules d'interfaces inter machines (ex : définition de structures, protocoles de communication, etc.).

    En effet, avoir du code compilant indifféremment en C et en C++ permet les points suivants :
    1. Même fichier source pour toutes les cibles, donc risques de régressions très fortement réduit lors des évolutions.
      Pour être honnête, on peut aussi bien sûr avoir ceci avec un mix C/C++, mais dans ce cas on n'a pas le point 2.
    2. Sur les cibles compilées en C++, évite d'avoir à utiliser un deuxième compilateur et/ou de la compilation conditionnelle à base de extern "C", qui pose parfois des soucis lors de l'édition de liens. Ou tout simplement parce qu'il faut "répéter" les réglages du compilateur C++ vers les réglages du compilateur C, ce qui est là encore une source de régressions.
    3. Permet de supporter les compilateurs C non ANSI qui existent sur certaines cibles, notamment les microcontrôleurs... En effet, certains de ces compilateurs ont un prototype pour malloc qui renvoie autre chose qu'un void*.
      Oui, ces compilateurs sont moches, vilains et tout ce que l'on veut, j'approuve des deux mains. Mais quand on n'a pas le choix parce que c'est le seul et unique compilateur existant pour cette cible, et que ladite cible est imposée par le client ou par l'historique, et bien il faut faire avec.


    Toutefois, en dehors de modules destinés et dédiés à la communication entre machines de nature assez différente (au niveau architecture, endianness, compilateurs et normes supportées), il est effectivement assez rare d'avoir l'utilité réelle de compiler en mode compatible C et C++. Mais le cas de figure existe, et ne doit pas être omis.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  16. #16
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    En effet, avoir du code compilant indifféremment en C et en C++ permet les points suivants :

    1. Même fichier source pour toutes les cibles, donc risques de régressions très fortement réduit lors des évolutions.
    Pour être honnête, on peut aussi bien sûr avoir ceci avec un mix C/C++, mais dans ce cas on n'a pas le point 2.
    2. Sur les cibles compilées en C++, évite d'avoir à utiliser un deuxième compilateur et/ou de la compilation conditionnelle à base de extern "C", qui pose parfois des soucis lors de l'édition de liens. Ou tout simplement parce qu'il faut "répéter" les réglages du compilateur C++ vers les réglages du compilateur C, ce qui est là encore une source de régressions.
    Ca ne ressemble pas un peu à :
    En effet, avoir du code compilant indifféremment en C et en C++ permet les points suivants :

    1. avoir du code compilant indifféremment en C et en C++, donc ...

    2. avoir du code compilant indifféremment en C et en C++, ...
    ?

    Bref, c'est justement ce qui n'a pas d'intérêt, selon moi. La compatibilité au niveau binaire est, de loin, plus importante et plus avantageuse que la compatibilité au niveau "source". On a des centaines de langages qui n'ont strictement rien à voir alors qu'on a toujours réussi à les rendre binaire-compatibles. Et puis, faire du C avec le C++ ... ça ne me dit pas grand-chose.

    Pour le 3, ça peut passer mais là c'est maintenant un problème purement C. Ca ça peut être une raison de caster malloc.

    Bref, avant de continuer le débat, je tiens à vous informer que la FAQ en question a été mise à jour (merci à Pouet_Forever) et cela datant du 30/12/2009 je crois. Je rappelle le lien : [FAQ] Faut-il caster malloc ?. C'est un bon compromis non (avec la même conclusion quand même ).

  17. #17
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par Melem Voir le message
    Ca ne ressemble pas un peu à :<snip>
    Non. Le premier est, bien entendu, faisable par plusieurs méthodes, dont la tienne et la mienne.
    La seconde, par contre, impose de régler (makefile, projet, machintruc) DEUX compilateurs au lieu d'un seul, avec des options par forcément simples à mettre en concordance... Sans parler du fait de peut-être devoir déployer un compilateur de plus.

    La compatibilité binaire est bien sûr très importante, mais une compatibilité au niveau source offre parfois de bien meilleurs avantages.

    Citation Envoyé par Melem Voir le message
    C'est un bon compromis non (avec la même conclusion quand même ).
    Cela a au moins le mérite d'être très nettement moins dogmatique que la version précédente... Je mentionnerais juste que les compilateurs non-ANSI ne sont pas forcément aussi vieux que ça !
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  18. #18
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Melem Voir le message
    Bref, avant de continuer le débat, je tiens à vous informer que la FAQ en question a été mise à jour (merci à Pouet_Forever) et cela datant du 30/12/2009 je crois. Je rappelle le lien : [FAQ] Faut-il caster malloc ?. C'est un bon compromis non (avec la même conclusion quand même ).
    ça s'améliore, mais ce n'est pas encore ça..

    Quand je lis :

    dans lequel caster malloc est non seulement inutile mais aussi de mauvais style).

    Je suis absolument désolé mais je suis résolument contre ces épithètes..

    Si on veut être une vraie FAQ, on devrait dire comme le dit comp.lang.c..

    "Il y a 2 styles. Chacun a ses pour et ses contres. Mais peu importe celui que vous prenez, votre style doit être homogène"



    PS: et à la limite, lister les aguments en faveur des 2 approches..

    MAis je ne vois pas ce qui vous permet de juger que c'est "un mauvais style"..

  19. #19
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Et si on remplaçait la réponse par ceci alors :
    soit vous compilez en mode "C++", c'est-à-dire que votre compilateur (qui est donc apparemment capable de compiler aussi bien du code C que du code C++) pense que votre code est écrit en C++ (dans lequel le cast de void * vers un autre type pointeur est obligatoire) et non en C (dans lequel ce cast est inutile). Généralement les fichiers sources C++ portent l'extension .cpp et les fichiers sources C l'extension .c, mais cela peut changer d'un compilateur à un autre. Il faut donc faire bien attention sur ce point là.
    J'ai enlevé le "de mauvais style", que je vais la garder pour moi-même, mais il faut quand même préciser que le cast est inutile, sinon ça ne répond pas la question. Que le lecteur décide ensuite de caster ou pas malloc, les int -> long, les type [] -> type *, etc., c'est son affaire, du moment qu'il sait que le cast n'est pas requis en C ANSI.

  20. #20
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    MAis je ne vois pas ce qui vous permet de juger que c'est "un mauvais style"..
    La FAQ pourrait se contenter de traduire la C FAQ (7.7 et 7.7b).

Discussions similaires

  1. aide sur fonction malloc
    Par chuko dans le forum C
    Réponses: 4
    Dernier message: 27/08/2008, 12h21
  2. Le bloc renvoyé par la fonction malloc
    Par clement_ dans le forum C
    Réponses: 4
    Dernier message: 08/10/2007, 15h12
  3. Réponses: 20
    Dernier message: 13/02/2007, 11h50
  4. Fonction malloc pour allocation
    Par Maria1505 dans le forum C
    Réponses: 6
    Dernier message: 06/11/2006, 16h38
  5. fonction malloc en c
    Par Invité(e) dans le forum C
    Réponses: 2
    Dernier message: 15/04/2006, 23h34

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