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 :

parametre (char const *) d'une fonction


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 100
    Par défaut parametre (char const *) d'une fonction
    Bonjour

    Pour tester l'interet d'utiliser const pour passer des pointeurs comme parametre d'entree ( non modifiable par un efonction ) j'ai utilise le code suivant
    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
     
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
     
     
    void  update ( char const * chr)
    {
       char * string = (char *) chr;
        string[0]= 'b';
     
    }
    int main (void) 
     
    { 
        char string[]="mokhtar";
        update(string);
        printf ( "result = %s\n", string);
     
    return 0 ; 
     
    }
    je m'attendais a ce la chaine que j'ai passe ne soit pas modifie
    surprise a l'execution de ce programme l achaine est modifiee
    result = bokhtar
    Remarque j'ai compile avec l'option -Wall

    Alors a quoi sert d'utiliser des const dans les parametres de fonctions?

  2. #2
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Par défaut
    ce code n'aurait pu compiler si tu n'avais pas casté le param en (char *).


    Si tu castes, tu en fais ce que tu veux ! c'est entre autre pour cela que l'on dit que le C est faiblement typé car en utilisant un cast, tu fais ce que tu veux de ton pointeur.

    Dans ton exemple le const indique que tu ne dois pas modifier le contenu du pointeur... Mais tu castes vers une variable char * qui elle est modifiable.
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    const n'est pas géré de façon très stricte en C et il est possible de violer cet attribut comme ici en mettant la valeur du pointeur sur const char (chr) dans un pointeur sur (non const) char (string). On peut alors modifier les données à partir de ce dernier pointeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void  update ( char const * chr)
    {
       char * string = (char *) chr;
        string[0]= 'b';
     
    }

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Il est également possible de faire la même chose en C++, si on ne prend pas soin de fuire comme la peste les cast "à la C" (le C++ proposant d'autres casts).

    En fait en C, il faut vraiment faire attention quand on mélange const avec des casts explicites.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    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
    de toutes façons, moi, fondamentalement, je ne comprend pas trop l'intérêt de const...

    Il y a les routines propres et les sales... (strtok est une sale..)

    Mais celui qui ECRIT la fonction, il sait ce qu'il veut faire. Et celui qui UTILISE, il lit la doc....

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Pour info, le prototype de strtok() (et sa contrepartie réentrante mais non-standard strtok_r()) suffit à montrer que la fonction modifie la chaîne passée en paramètre. C'est un des rôles de const.

    Si tu veux une vraie fonction sale, prends strchr() (qui en C++ est surchargée pour éviter cela, du moins dans la version Microsoft de la SL).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    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 Médinoc Voir le message
    Si tu veux une vraie fonction sale, prends strchr() (qui en C++ est surchargée pour éviter cela, du moins dans la version Microsoft de la SL).

    Ben strchr ne modifie pas la chaine entree, que je sache ...

    Et pour strtok, c'est surtout qu'elle rend la chaine inutilisable... Si elle ne faisait que la modifier, passe encore...

  8. #8
    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 souviron34 Voir le message
    Ben strchr ne modifie pas la chaine entree, que je sache ...
    Non, mais elle accepte l'adresse d'une chaine non modifiable et retourne l'adresse d'une chaine modifiable qui pointe sur la même chaine !

    C'est crade...

    Ceci compile sans problèmes :
    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 <stdio.h>
    #include <string.h>
     
    int main (void)
    {
       char const *s = "Hello xorld";
       char *p = strchr (s, 'x');
     
       if (p != NULL)
       {
          *p = 'w';
       }
       printf ("'%s'\n", s);
     
       return 0;
    }
    Mais invoque un comportement indéfini...

    (Sous Windows, crash...)

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Et la chaîne modifiée par strtok() n'est pas "complètement inutilisable" : Elle est modifiée de manière exactement documentée, puisqu'elle est systématiquement tronquée après le premier token.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  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
    Citation Envoyé par Médinoc Voir le message
    Et la chaîne modifiée par strtok() n'est pas "complètement inutilisable" : Elle est modifiée de manière exactement documentée, puisqu'elle est systématiquement tronquée après le premier token.
    c'est ce que j'appelle completement inutilisable... tu as perdu ce qu'il y a apres... je trouve juste que c'est plus crade que strschr..

    mais on va pas "s'enfarger dans les fleurs du tapis", comme on dit par ici

  11. #11
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    de toutes façons, moi, fondamentalement, je ne comprend pas trop l'intérêt de const...
    Celui de toute vérification statique: mettre une partie de la doc dans le langage pour permettre au compilateur de vérifier qu'elle est toujours correcte.

    (Le cast du premier message est un moyen de dire au compilateur, ça n'a pas l'air correct mais je sais ce que je fais).

  12. #12
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Le code du PO me semble normal car pour ne pas pouvoir modifier la chaîne il faudrait écrire const char * là ce n'est pas le cas donc on peut modifier la chaîne

    char const * ptr rends le pointeur constant, tu ne peux pas 'déplacer' le pointeur soit ptr++ échoue à la compilation c'est donc bien la variable pointeur qui est constante et pas l'objet pointé

  13. #13
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par hegros Voir le message
    Le code du PO me semble normal car pour ne pas pouvoir modifier la chaîne il faudrait écrire const char * là ce n'est pas le cas donc on peut modifier la chaîne

    char const * ptr rends le pointeur constant, tu ne peux pas 'déplacer' le pointeur soit ptr++ échoue à la compilation c'est donc bien la variable pointeur qui est constante et pas l'objet pointé
    Tu confonds, il n'y a pas de difference entre const char* et char const*. char * const par contre a le pointeur constant.

Discussions similaires

  1. L'adresse d'un char renvoyé par une fonction ?
    Par tintin72 dans le forum C++
    Réponses: 5
    Dernier message: 17/10/2007, 11h05
  2. Définir une "Public Const" avec une fonction
    Par bernardmichel dans le forum VBA Access
    Réponses: 6
    Dernier message: 29/09/2007, 15h16
  3. Réponses: 11
    Dernier message: 27/06/2007, 15h06
  4. Tableau de char[] passé dans une fonction
    Par Joratois dans le forum C
    Réponses: 26
    Dernier message: 07/06/2007, 15h06
  5. Réponses: 5
    Dernier message: 29/09/2006, 17h17

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