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 :

[Théorie] Justifier les variables globales


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut [Théorie] Justifier les variables globales
    Bonjour

    J'ai une petite question plus théorique que la plupart des posts de ce forum.

    Il faut éviter au maximum l'utilisation de variables globales. Cependant, dans un projet, j'ai deux structures dont pratiquement toutes les fonctions ont besoin.
    Par ailleurs, le projet utilisant GTK+, je me retrouve un peu limité quant au nombre de paramètres que je peux passer aux fonctions callback.
    Alors j'ai décidé de mettre les deux structures en question (je parle de la définition de la structure mais également de l'instance de la structure) en globale.
    Ca simplifie considérablement mon programme et il n'y a pas vraiment de problèmes de maintenance puisque, comme je l'ai dit, pratiquement toutes les fonctions en ont besoins.

    Avec le projet, on doit rendre un rapport écrit qui contient toutes les justifications des algos utilisés ainsi que toute autre particularité. Les variables globales en ont partie.

    Comment justifieriez-vous leur utilisation? Le fait de dire que toutes les fonctions en ont besoin est-elle une bonne justification?

    Nas'

    PS : ce message n'est peut-être pas dans le bon forum mais je ne vois pas où le mettre...

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: [Théorie] Justifier les variables globales
    Citation Envoyé par Nasky
    J'ai une petite question plus théorique que la plupart des posts de ce forum.

    Il faut éviter au maximum l'utilisation de variables globales.
    Sais-tu pourquoi ?

    http://emmanuel-delahaye.developpez....s.htm#globales
    Cependant, dans un projet, j'ai deux structures dont pratiquement toutes les fonctions ont besoin.
    Il suffit de passer l'adresse aux fonction. Si il n'y a qu'un parametre genre void *, passer l'adresse d'une structure 'chapeau' (user context) qui contient l'adresse des deux structres (ou les deux structures elle-même, peu importe). Nul ne peux prevoir combien de fois sera appelé ton code dans le même espace utilisateur. Il faut donc rester contextuel le plus longtemps possible.
    Pas de Wi-Fi à la maison : CPL

  3. #3
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Personnellement, je traiterais ces deux globales dans un/deux fichier(s) à part avec des fonctions d'accès.
    Mon(es) .h définirai(en)t l'interface d'accès/modification à ces données.
    Les fonctions ont-elles vraiment besoin de connaître le detail des structures ?
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  4. #4
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Merci pour vos réponses.

    Emmanuel, c'est effectivement à cause du paramètre de type void* du callback que j'ai utilisé les globales. J'ai pensé à faire comme tu le suggères, à savoir la structure regroupant les deux autres, mais ça allourdit l'écriture.
    Et honnêtement, je ne vois pas du tout en quoi les mettre en globale empêche une quelconque maintenance par exemple.

    Personnellement, je traiterais ces deux globales dans un/deux fichier(s) à part avec des fonctions d'accès.
    Mon(es) .h définirai(en)t l'interface d'accès/modification à ces données.
    Désolé, je n'ai pas très bien compris ce que tu veux dire par là.
    Les fonctions ont-elles vraiment besoin de connaître le detail des structures ?
    Tu veux dire, ont-elles besoin d'accéder à tous les membres de la structure? Si c'est le cas, alors oui. La structure contient des coordonnées donc c'est nécessaire les connaitre à tout moment par n'importe quelle fonction.

    Nas'

  5. #5
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut Re: [Théorie] Justifier les variables globales
    Citation Envoyé par Nasky
    Comment justifieriez-vous leur utilisation? Le fait de dire que toutes les fonctions en ont besoin est-elle une bonne justification?
    Oui. Simplifer le code est une des utilisations des variables globales.
    Regarde la variable errno par exemple. Elle est déclarée en globale dans errno.h. Ensuite, les fonctions qui en ont besoin mettent à jour cette variable. Pour l'utilisateur, c'est très propre : on n'a pas à promener un argument errno dans chaque fonction...

  6. #6
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Je voulais dire que par exemple pour lire la valeur d'une variable globale entiere j'aurais une fonction MyVarGetValue() et pour modifier la valeur de cette variable, un MyVarSetValue(val) , je n'aurais pas directement accès à la variable.
    c'est un peu plus protégé, encapsulé.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: [Théorie] Justifier les variables globales
    Citation Envoyé par DaZumba
    Regarde la variable errno par exemple. Elle est déclarée en globale dans errno.h. Ensuite, les fonctions qui en ont besoin mettent à jour cette variable. Pour l'utilisateur, c'est très propre : on n'a pas à promener un argument errno dans chaque fonction...
    errno est probablemnt une des plus grosses erreurs du C... En effet, on ne sait jamais qui a réellement mis à jour celle-ci. De plus, c'est une Non Modifiable L-value [1], ce qui fait qu'il n'est pas possible d'écrire dedans directement, ce qui est un moindre mal pour une globale...

    ------------------
    [1] Il se peut que cette faculté ne soit pas exigée par la norme, mais soit une conséquence la QoI (Quality of Implementation). Si quelqu'un a le courage de vérifier dans Le Livre...
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Trap D
    Je voulais dire que par exemple pour lire la valeur d'une variable globale entiere j'aurais une fonction MyVarGetValue() et pour modifier la valeur de cette variable, un MyVarSetValue(val) , je n'aurais pas directement accès à la variable.
    c'est un peu plus protégé, encapsulé.
    Oui, mais ça ne résout pas les problèmes de réentrance. Le problème des globales ne se resume pas au simple problème de l'accessibilité.
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Citation Envoyé par Trap D
    Je voulais dire que par exemple pour lire la valeur d'une variable globale entiere j'aurais une fonction MyVarGetValue() et pour modifier la valeur de cette variable, un MyVarSetValue(val) , je n'aurais pas directement accès à la variable.
    Ah ok, tu parles de "méthodes accesseurs" (même si ce terme n'existe pas en langage non objet) alors. Mais comme les fonctions qui accédent à mes variables globales les modifient aussi (chacune à sa façon), ce n'est pas très pratique je pense.

    Dans quels genre de situations les globales sont-elles alors acceptables?
    Car je ne vois vraiment pas en quoi les globales dans mon cas posent problèmes. Qu'elles soit globales et qu'on y accédent donc directement, ou bien qu'elles soient locales et qu'on les passent par paramètre, changera quoi?

    Nas'

  10. #10
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Ce peut être utile, par exemple, si tu as de grosses structures nécessaires en lecture.
    Ainsi, une fonction d'initialisation est appelée une seule fois, elle remplit la structure de donnée avec tout ce qui va bien, et après, les accès se font en lecture seule (on ne touche plus à la structure de donnée)
    Exemple : Une grande table de hachage contenant les sockets associées à un service donné, disponibles en consultation.
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  11. #11
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Donc si la plupart de mes fonctions sont codées de telle sorte qu'elles ne modifient pas ma structure, alors la mettre en globale semble correct?
    Car en relisant mon code, je me rend compte que la plupart ne font que lire les données contenues dans la structure. Seules 2 fonctions la modifient (contre une dizaine qui ne fait que lire). Dans ce cas, l'emploi de globales est-il justifié?

    Le problème des globales ne se resume pas au simple problème de l'accessibilité.
    Quelles sont les autres contraintes?
    Car sur ta page web, on peut lire :
    Un usage abusif des variables globales est fortement déconseillé pour diverses raisons (manque de lisibilité, maintenance et compréhension du code difficiles, effets secondaires indésirables, sécurité précaire, code non réentrant...) La liste est longue...
    Un "abus" contribue clairement à rendre le code moins clair. Mais après, dans mon cas par exemple où seules les 2 structures les plus importantes (niveau nombre d'accès) sont en globales, il n'y a pas vraiment de problème je trouve. Ensuite, il y a les "effets indésirables" mais quand on sait ce qu'on fait (personne d'extérieure au projet va retoucher au code), on peut facilement les éviter. Pareil pour la sécurité (je pense que tu parles des accès lecture/écriture)...
    Par contre, je ne comprend pas le terme "réentrant" :

    Nas'

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Nasky
    Par contre, je ne comprend pas le terme "réentrant" :
    La réentrance est capacité d'une fonction d'être appelée alors qu'elle est déjà en cours d'exécution. Sans cette possibilité, la programmation par threads est impossible. Les fonctions réentrantes sont aussi appelées 'thread-safe'.

    Pour qu'une fonction soit réentrante, elle ne doit pas utiliser de globales, qu'elles soient publiques ou internes (static)

    L'un des problèmes graves induit par les globales et le fait qu'elles ne sont instanciées qu'une seule fois par processus. Ca signifie que si une fonction modifiant une globale est appelée par une fonction modifiant la globale, le comportement est indéterminée. C'est particulièrement grave avec les globales 'cachées' comme celle de strtok() qui interdit des appels imbriqués de strtok() (et qui justifient l'extension POSIX strtok_r() ... comme réentrant).

    La solution à ce problème consite à utiliser des contextes (pointeurs sur structures de données), ce qui conduit tout naturellement à une organisation du code autour des données, et non le contraire. C'est comme ça que la POO a démarré.

    http://emmanuel-delahaye.developpez.com/tad.htm
    Pas de Wi-Fi à la maison : CPL

  13. #13
    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
    Attention, une fonction peut être thread-safe sans être réentrante. Enfin, sous Unix, pas sûr. Mais sous les OS qui supportent les threads en Natif (au hasard: Windows) des fonctions comme strtok() ou GetLastError() possèdent un espace de stockage propre à chaque thread; Elles ne sont pas réentrantes pour autant.
    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.

  14. #14
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut Re: [Théorie] Justifier les variables globales
    Citation Envoyé par Emmanuel Delahaye
    errno est probablemnt une des plus grosses erreurs du C... En effet, on ne sait jamais qui a réellement mis à jour celle-ci. De plus, c'est une Non Modifiable L-value [1], ce qui fait qu'il n'est pas possible d'écrire dedans directement, ce qui est un moindre mal pour une globale...
    Je ne sais pas si errno est du bad design ou non, j'imagine que cela depend du point de vue. Le fait d'eviter de ballader un argument err de fonction en fonction est assez pratique. Mais c'est certainement le seul avantage.

    Sinon, d'apres la norme (C99, mais je doute que cela ait change), errno n'est pas forcement une globale (meme s'il est plus simple de l'implementer ainsi). C'est une macro, qui doit devenir une modifiable lvalue de type int.

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 07/04/2006, 01h10
  2. Les variables globales en C++
    Par jeje99 dans le forum C++
    Réponses: 4
    Dernier message: 03/02/2006, 15h52
  3. Supprimer la mémoire utilisée par les variables globales
    Par dnaprotector dans le forum OpenGL
    Réponses: 4
    Dernier message: 21/07/2005, 13h18
  4. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  5. les variables globales static
    Par gRRosminet dans le forum C
    Réponses: 8
    Dernier message: 27/04/2002, 08h34

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