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 :

Variables dans un bloc


Sujet :

C++

  1. #1
    Membre confirmé Avatar de Gui13
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Par défaut Variables dans un bloc
    Bonjour à tous,

    Voilà je suis confronté à un petit problème: dans les blocs d'accolades, on est d'accord que les variables créées sont temporaires (elles disparaissent à la fin du bloc)?

    Voici 2 codes très simples qui me chiffonnent:

    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
    #include <stdio.h>
    #include <iostream>
     
    using namespace std;
     
    int ajoute(int & d){
      int k = d+1;
      if(k == 3){
        int e = 3;
        cout << d << endl;
      }
      cout << d << endl;
    }
     
    int main(){
      int d = 2;
      ajoute(d);
      return 0;
    }
    Me donne la sortie suivante (normal, j'ai envie de dire):
    Maintenant celui-ci:
    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
    #include <stdio.h>
    #include <iostream>
     
    using namespace std;
     
    int ajoute(int & d){
      int k = d+1;
      if(k == 3){
        int d = 3; //cette variable a le même nom que l'argument que la fonction a recu!
        cout << d << endl;
      }
      cout << d << endl;
    }
     
    int main(){
      int d = 2;
      ajoute(d);
      return 0;
    }
    Me donne la sortie :
    Le probleme, c'est donc que dans ce bloc "if{...]", je ne peux plus avoir accès à l'argument de la fonction ajoute(). Et puis même, comment le compilateur fait pour ne pas s'emmeler les pinceaux?

    Bizarre, bizarre, vous avez une explication?

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    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 392
    Par défaut
    Le premier cout est dans le bloc interne, il prend donc la variable d du bloc interne. C'est aussi simple que ça: Le compilo utilise une pile pour les noms de variables (typiquement, une pile de "tables des symboles").
    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.

  3. #3
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    je ne vois pas trop le problème:
    déjà pour des arguments de fonction, il faut éviter à tout prix des lettres comme "d"...préférer des nom plus signification genre "valeur"
    genre si tu utilise un argument appelé "i", et que tu utilise des boucles...oulalala....

    ensuite pour le coup du if, je crois qu'à l'intérieur d'accolades, ca utilise la pile...seule la variable locale est vue dans le if, une fois sorti du if cette valeur disparait et l'argument de la fonction réapparait

    enfin évite de faire ce type de double déclaration...si tu fais ça dans un programme de 5000lignes de code et que tu dois debugger 3mois après ça peut être délicat

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    En montant le niveau de warning du compilateur et suivant les compilateurs, il n'est pas possible d'avoir un message qui permette de détecter ce genre de situation.

    Il me semble me rappeler que sur le compilateur HP-UX, il y avait des messages de ce genre "Warning symbol 'toto' is overriding another symbol".

    En tout cas, le compilateur de Visual Studio 2005 SP1 ne signale rien, je viens de tester.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Salut,

    C'est très bien de se poser ce genre question, cela veut dire que tu t'intéresse au fonctionnement du langage. Félicitations, c'est une bonne approche.

    Quand tu dis :
    Citation Envoyé par Gui13 Voir le message
    Le probleme, c'est donc que dans ce bloc "if{...]", je ne peux plus avoir accès à l'argument de la fonction ajoute().
    C'est une bonne analyse, cela veut dire qu'en utilisant le même nom de variable pour représenter deux choses différentes, tu te prives de l'une des deux.

    Citation Envoyé par Gui13 Voir le message
    Et puis même, comment le compilateur fait pour ne pas s'emmeler les pinceaux?
    Ne t'inquiètes pas les compilateurs sont VRAIMENT très forts. A un point que l'on a du mal à concevoir. Si tu te penches un jour sur les problèmes d'optimisation de code par le compilateur, tu verras à quel point ils peuvent "penser" à des choses qui sont loin au delà de notre intelligence.

    Donc pas de soucis, ils ne s'emméleront pas les pinceaux.

    Par, contre, nous si.

    Et comme nous ne sommes pas aussi fort qu'eux, on fait tout pour se simplifier la tâche. En particulier, on essaie d'éviter ce dont tu parle, à savoir nommer deux variables de la même façon.

    En général, on essaie d'utiliser des noms de variables clairs et lisibles, pareil pour les noms de fonction

    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 <iostream>
     
    using namespace std;
     
    int afficheEntierPlus1PuisEntier(int& entierAAfficher){
      int entierAAfficherPlus1 = entierAAfficher + 1;
      if(entierAAfficherPlus1  == 3){
        cout << entierAAfficherPlus1  << endl;
      }
      cout << entierAAfficher  << endl;
    }
     
    int main(){
      int unEntierQueLonVaAfficher = 2;
      afficheEntierPlus1PuisEntier(unEntierQueLonVaAfficher);
      return 0;
    }
    Bravo et courage !

  6. #6
    Membre confirmé Avatar de Gui13
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Par défaut
    Ah! Merci pour ces réponses, j'y vois un peu plus clair.

    Pour expliquer un peu la démarche: je suis dans une boite qui a un code assez bizarre en C++ (avec tout un tas de macros pour déclarer les classes, une config en XML et des choses que je ne comprends pas encore).

    En naviguant dans le code j'ai trouvé des fonctions où justement le nom de variable dans un if{} était le même que l'argument que la fonction recevait. C'est (je pense) à des fins de lisibilité, puisque dans mon cas le nom des méthodes est fait de manière à sembler plus naturel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Request request(...);
    request.Answer();
    Donc que ce soit la requête "recue" ou la requête à "renvoyer", ils utilisent le même nom de variable pour plus de lisibilité.

    L'exemple au dessus m'a juste aidé à confirmer que ca marchait. Dans la réalité, de mon côté, je trouve ca un peu débile...

  7. #7
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Citation Envoyé par Gui13 Voir le message
    Donc que ce soit la requête "recue" ou la requête à "renvoyer", ils utilisent le même nom de variable pour plus de lisibilité.
    Je serais vraiment intéressé de voir un code dans lequel le masquage de variables rend le code plus lisible. En général, c'est le contraire.

    Peux-tu nous le montrer ?

    Citation Envoyé par Gui13 Voir le message
    L'exemple au dessus m'a juste aidé à confirmer que ca marchait. Dans la réalité, de mon côté, je trouve ca un peu débile...
    Il y a quelques mois, j'ai été amené à aider un collaborateur qui n'arrivait pas à débuger une vielle application à cause d'un problème similaire (bon il ne s'agissait pas de masquage, mais de réutilisation d'une variable).

    A cause de cela, le pauvre avait étudié pendant 3 jours la mauvaise partie du code.

    Un bon code devrait être facilement maintenable pour éviter ce genre de choses. En général l'utilisation du masquage nuit à cet objectif.

  8. #8
    Membre confirmé Avatar de Gui13
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Par défaut
    Non c'est pas possible pour le code je pense (CND) mais c'est dans l'esprit du code au dessus:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int foo(Request & request){
       if (configured(request))
       {
          Request request(...arguments...);
          send(request);
       }
       request.Answer():
       return 0;
    }

Discussions similaires

  1. Déclaration d'une variable dans un bloc
    Par Nadd dans le forum Débuter
    Réponses: 11
    Dernier message: 09/03/2010, 16h24
  2. utilisation variable dans un bloc
    Par keks42 dans le forum Débuter
    Réponses: 3
    Dernier message: 23/04/2009, 01h34
  3. [Linq to Sql] [VB 2008] Variable dans un bloc englobant
    Par Bob Langlade dans le forum Linq
    Réponses: 0
    Dernier message: 05/03/2009, 02h29
  4. Réponses: 2
    Dernier message: 21/09/2007, 15h51
  5. Utilisation d'une variable dans un bloc pl/sql
    Par paris2000fr dans le forum PL/SQL
    Réponses: 2
    Dernier message: 29/03/2006, 14h08

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