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 constants et vitesse d'exécution


Sujet :

C

  1. #1
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut Pointeurs constants et vitesse d'exécution
    Bonjour,

    J'ai deux questions en rapport avec les pointeurs constants et les constantes de manière générales :

    Soit la déclaration suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct {
          unsigned char** matrice;
          int nbL, nbC; // taille matrice
    }Foo;
    1) En C++, on peut définir des fonctions constantes de manière a être sur de ne pas modifier l'état d'un objet à travers cette fonction (très utile pour les getter par exemple). En C, ce mécanisme pour les fonctions n'existent pas et donc je me demandais comment je pouvais protéger la modification de mon tableau 2D à travers une fonction (ou autre) ? En gros, je ne souhaite pas pouvoir faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void func (Foo* obj)
    {
    // je voudrais que le compilateur plante sur la ligne suivante
    obj->matrice[0][0] = 5;
    }
    Si j'utilise, const Foo* const obj ca ne marche pas, car le compilateur m'interdit bien obj->matrice = ... ou alors obj = ... mais pas ce que je veux

    Le problème c'est que parfois, j'ai besoin de modifier l'intérieur de mon tableau. Je ne peux donc pas déclarer mon tableau 2D comme étant constant dès le départ...

    2) Au niveau de la vitesse d'exécution du programme, est ce que les pointeurs constants et/ou qui pointent sur des constantes ont plus rapide que les pointeurs classiques lors des appels des fonctions ? Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void func(Foo* pt)
    {
    // blabla en lecture seule (pt ne sera pas modifié, ni son contenu)
    }
     
    // VERSUS
    void func(const Foo* const pt)
    {
    // blabla en lecture seule (pt ne sera pas modifié, ni son contenu)
    }
    Y'a t-il une différence de rapidité ou alors c'est pareil ?

    Voilà, merci d'avance et bonne journée
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  2. #2
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 62
    Points : 162
    Points
    162
    Par défaut
    Bonjour,
    En soit le tableau n'a pas à être constant mais tu peux essayer de le faire croire dans la structure en utilisant un pointeur vers tableau constant.
    Il faudrait utiliser deux types : un normal et un lecture seule.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct {
          unsigned char** matrice;
          int nbL, nbC; // taille matrice
    }Foo;
     
    typedef struct {
          const unsigned char*const * matrice;
          int nbL, nbC; // taille matrice
    }ConstFoo;
    Avec un cast tu t'assures que le tableau n'est pas modifiable. Les champs et leur taille ne changent pas donc aucun problème d’accès.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void func (ConstFoo* (ConstFoo*)obj)
    {
    // je voudrais que le compilateur plante sur la ligne suivante
    obj->matrice[0][0] = 5;
    }
    Je n'ai pas testé se genre de code donc à vérifier.

    Concernant ta seconde question, je dirais que le temps d’exécution est le même dans les deux cas. Le const n'est qu’une sécurité au moment où tu compiles. Comme ce sont des paramètres de fonction, ils doivent être stockés comme les autres sur la pile donc rien de spécifique =/.

  3. #3
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Intéressant comme concept, je vais essayer dès que j'ai un peu de temps
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Franchement, ces casts sentent plus le soufre qu'autre chose.

    En C, le seul moyen sûr est d'utiliser le principe du Type Abstrait de Données, en mettant tous les accesseurs dans des fonctions et en ne définissant pas la structure dans le header:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /*Toto.h*/
     
    struct Toto;
     
    struct Toto* NewToto();
    void DeleteToto(struct Toto *);
     
    int* GetTotoTablInt(struct Toto *);
    int const* GetTotoTablIntC(struct Toto const*);
    Malheureusement, à moins de posséder un compilateur capable de Link-Time Code Generation (LTCG), cela se fera au détriment de la performance. L'alternative est d'utiliser des fonctions inline dans le header, mais dans ce cas rien n'empêche le code utilisateur de les bypasser pour taper directement dans la structure.

    Peut-être qu'une bonne solution serait de passer par un fichier source séparé pour la phase de dev et la build Debug, et de passer en Inline pour la performance dans la build Release.
    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é
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Malheureusement, à moins de posséder un compilateur capable de Link-Time Code Generation (LTCG), cela se fera au détriment de la performance. L'alternative est d'utiliser des fonctions inline dans le header, mais dans ce cas rien n'empêche le code utilisateur de les bypasser pour taper directement dans la structure.
    Oui, j'y ai pensé aux accesseurs et mutateurs mais comme tu le dis, cela réduit les performances
    Le inline est valable en C ? Je pensais que c'était uniquement en C++. Dans ce cas, c'est une alternative pour moi puisque je ne bypasserai pas les accesseurs
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    À ma connaissance, les standards GNU90 et C99 supportent tous les deux inline, et Visual Studio a sa propre version pour le C (et supporte la LTCG au moins depuis Visual 2005).
    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é
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Effectivement, je viens de vérifier. Normalement je code en C++ donc je n'ai pas de soucis de ce genre grâce au paradigme objet.
    Mais en C, j'avoue que ce n'est pas si évidement que cela.

    Merci
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

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

Discussions similaires

  1. [SQL]ADODataset et ADOQuery Vitesse d'exécution.
    Par aityahia dans le forum Bases de données
    Réponses: 1
    Dernier message: 30/06/2008, 19h44
  2. Modifier une chaîne d'un pointeur constant
    Par oranoutan dans le forum C
    Réponses: 7
    Dernier message: 25/05/2007, 16h32
  3. Au sujet de la vitesse d'exécution des programmes
    Par emie31 dans le forum Langage
    Réponses: 5
    Dernier message: 09/11/2006, 13h42
  4. pointeurs constants et prototype de ma fonction
    Par salseropom dans le forum C
    Réponses: 3
    Dernier message: 23/05/2006, 18h03
  5. Réponses: 4
    Dernier message: 02/04/2006, 18h42

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