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 :

Déclaration de variables dans une boucle


Sujet :

C

  1. #1
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut Déclaration de variables dans une boucle
    Bonjour,
    Je voudrai savoir si de déclarer des variables dans une boucle - comme for - fait ralentir le système, ou c'est négligeable.
    N'est-il pas préférable de déclarer sa variable avant la boucle, et de la remettre à zéro s'il le faut ? y a un t-il un réel coup physique de déclarer sa variable ou non dans une boucle ?
    Lors d'un deuxième tour de boucle, la déclaration se fait de nouveau, l'espace pris avant est supprimé ? le système prend-il la même adresse que précedement ?

    merci d'avance

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 388
    Points : 23 707
    Points
    23 707
    Par défaut
    Bonjour,

    C'est une question pertinente, que trop de gens « négligent » effectivement aujourd'hui mais, dans le cas présent, c'est négligeable, car ta variable va être déclarée dans la pile, puis accédée via un offset par rapport à un pointeur de base. Et l'allocation d'espace dans cette pile se fait simplement en soustrayant la taille de l'espace nécessaire. Donc, la différence entre les deux se résumera simplement à des valeurs d'offset différentes. Réinitialiser la variable a bien sûr un coût (faible), mais tu nous informes que tu le fais de toutes façons.

    C'est donc une bonne chose de garder, en C, ses variables le plus « localement » possible pour réduire au minimum la taille instantanée de la pile, et ça devient même salutaire sur de gros projets. GCC propose même un flag pour nous alerter lorsqu'une variable en masque une autre de même nom mais de plus haut niveau, ce qui est pourtant parfaitement légal (et même utile) en C. Ça nous a sauvés plusieurs fois.

    En revanche, ce n'est pas du tout le cas de manière universelle, et ça l'est même très rarement sur les langages interprétés, et mêmes les langages compilés de plus haut niveau comme Java ou même C++ lorsque tu instancies des objets, à cause du RAII : chaque re-déclaration d'objet effectivement le rappel du constructeur et tout le processus interne qui s'en suit, comme des allocations diverses. Dans ce genre d'environnement, il vaut mieux privilégier la réutilisation des objets lorsqu'ils dépassent les simples types natifs.

  3. #3
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    okay, donc faire au mieux déclarer sa variable le plus tard, mais si je déclare ma variable en début de bloc, et qu'à partir de ma boucle, je me retrouve à nouveau au niveau de la déclaration, il y a automatiquement liberation de mémoire de l'ancien, et nouvel emplacement pour la nouvelle variable ?
    et donc y a t-il une importance de déclarer en milieu de bloc, en début ou en fin ?

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 388
    Points : 23 707
    Points
    23 707
    Par défaut
    Citation Envoyé par dafpp Voir le message
    okay, donc faire au mieux déclarer sa variable le plus tard, mais si je déclare ma variable en début de bloc, et qu'à partir de ma boucle, je me retrouve à nouveau au niveau de la déclaration, il y a automatiquement liberation de mémoire de l'ancien, et nouvel emplacement pour la nouvelle variable ?
    Non. Une variable locale déclarée à la compilation (c'est-à-dire sans faire appel à une fonction explicite comme malloc()) a la durée de vie de son bloc. Elle est visible par tout ce qu'il contient, et seulement par ce contenu (sauf artifices style pointeurs passé à une fonction appelée depuis ce bloc).

    et donc y a t-il une importance de déclarer en milieu de bloc, en début ou en fin ?
    En principe, C89 t'oblige à tout déclarer au début d'un bloc, avant la première ligne de code. Et ceci justement parce que l'on avait besoin de connaître à l'avance la taille du cadre de pile pour pouvoir générer en conséquence le code qui va l'utiliser. Depuis, des normes plus récentes ont levé cette restriction, mais c'est toujours une bonne idée de t'y contraindre si tu codes en C. C'est plus facile de s'y retrouver ensuite, et ça permettra à donc programme de compiler partout.

  5. #5
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    Je vois donc, de toute façon, peu importe où je déclare ma variable, tout ce qui est déclaré a son forcement son espace mémoire, même si on va jamais dans ce bloc.

    Donc je déclare tout en début de fonction, et je fais attention à remettre l'espace mémoire à zéro.

    merci

    edit: j'y pense mais ce qui est des déclarations de variables en début de bloc, sur quel système ça ne marcherait peut-être pas ? et si oui pourquoi ? Tant que le compilo prend en compte la norme C89 c'est bon ?

  6. #6
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    C'est donc une bonne chose de garder, en C, ses variables le plus « localement » possible pour réduire au minimum la taille instantanée de la pile,
    J'ai un gros doute sur le fait que chaque fois que l'on rentre dans un bloc (if for while...) la pile bouge... Je ne sais pas si c'est spécifié dans le standard du langage ou de l'ABI, mais il faudrait que je trouve confirmation de cela...

    A noter aussi que certaines variables peuvent êtres mises dans des registres et ne jamais exister en mémoire...

    Tout cela ne répond pas directement à ta question, mais bon, j'ai un doute qui me fait me réveiller là.

  7. #7
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    Ce qui fait grandir mon doute aussi, et qui peut influencer ma façon de faire.
    Donc j'attends une réponse à ton psot.

  8. #8
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    à vrai dire, on s'en fiche, si c'est dans la pile où pas..

    Ce n'et pas l'argument pour cette manière de faire.

    L'argument est de ne définir des variables que là où on en a besoin.

    Personnellement (mais je suis de la vieille école) je préfère faire "à la C89", et définir toutes mes variables en début de fonction. Je trouve cela plus "maintenable" .. et avec un point de vue global sur ce qu'utilise la fonction.

    Maintenant, la politique de cerner au plus près se défend également, bien que je trouve cela moins "maintenable" et plus difficile à lire/comprendre. Mais ce point de vue est personnel..

    En tous cas, le fait que cela soit sur la pile ou non n'est pas l'argument pour lequel cela a été inclus en C99.. : c'est celui de la portée.

  9. #9
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Bon, c'est un long débat qu'on a déjà eu à plusieurs reprises. Personnellement, je préfère définir une variable à un moment où je suis en mesure de l'initialiser avec une valeur qui fait sens, et éventuellement la définir avec le qualificatif const, si ça aide à document mon intention. Dans cette mesure, restreindre la portée d'une variable au bloc où elle est utilisée me semble une bonne pratique.

    A noter que C90 n'oblige aucunement de définir ses variables en début de fonction, mais en début de bloc. Ainsi, même en C90, je trouve que c'est une bonne pratique de restreindre au maximum la portée d'une variable à l'endroit où elle est utilisée et où elle peut être initialisée avec une valeur qui fait sens.

    Je comprends et respecte toutefois les arguments de souviron34, qui se défendent et qui sont partagés par beaucoup de monde. Personnellement, si une variable n'est utilisée que dans le corps d'une boucle, je n'hésiterais pas à la définir dans la boucle. Le overhead, du point de vue de la performance, ne doit effectivement pas être significatif.

    Avec mes meilleures salutations

    Thierry

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 388
    Points : 23 707
    Points
    23 707
    Par défaut
    Citation Envoyé par valefor Voir le message
    J'ai un gros doute sur le fait que chaque fois que l'on rentre dans un bloc (if for while...) la pile bouge... Je ne sais pas si c'est spécifié dans le standard du langage ou de l'ABI, mais il faudrait que je trouve confirmation de cela...
    Que la pile bouge ou non au sein d'un tour d'un même tour de boucle importe peu en C. Par contre, c'est nécessaire quand tu passes d'un bloc à l'autre et que ceux-ci sont situés au même niveau, c'est-à-dire : inclus dans un même troisième bloc. Si depuis un bloc A, je rentre dans un bloc B et que j'y déclare un gros tableau de 512 ko, lorsque je quitte le bloc, je m'attends effectivement à ce que ces 512 ko soient libérés, ne serait-ce que parce que je peux avoir envie de déclarer un autre gros tableau dans le bloc suivant.

    Après, le compilateur peut faire des optimisations s'il a une vision suffisamment lointaine du déroulement de ta séquence, mais cela ne peut pas être une généralité, ne serait-ce que parce qu'entre les deux, tu peux avoir besoin d'appeler une fonction par exemple.

    Et cela devient même critique lorsque tu utilises des fonctions récursives : il est courant d'avoir plusieurs points de réentrance dans une telle fonction et si le compilateur prévoit systématiquement au plus large, on risque d'atteindre les limites des ressources bien avant de les avoir réellement toutes utilisées.

  11. #11
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Points : 380
    Points
    380
    Par défaut
    je ne sais pas si la norme impose un nouveau cadre de pile pour chaque bloc, mais je suis certain que c'est le cas si ce bloc est le corps d'une fonction.
    pour faire
    bloc A
    {
    bloc B
    bloc C
    }
    je pense qu'on peut faire
    definir fonction A
    definir fonction B
    bloc A
    {
    call B;
    call C;
    }
    pour que les cadres de pile soient différents.

    A+

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 388
    Points : 23 707
    Points
    23 707
    Par défaut
    Citation Envoyé par anacharsis Voir le message
    je ne sais pas si la norme impose un nouveau cadre de pile pour chaque bloc, mais je suis certain que c'est le cas si ce bloc est le corps d'une fonction.
    pour faire […] pour que les cadres de pile soient différents.
    Oui mais en l'occurence, on traite du problème opposé : on veut savoir si la pile reste ou non constante lorsque l'on navigue d'un bloc à l'autre au sein d'une même fonction.

  13. #13
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Ce que la norme dit, c'est que la durée de vie d'un l'objet non VLA commence au début du bloc (même si la déclaration n'est pas en début de bloc) jusqu'à la fin du bloc où il est défini. Pour les VLA, du point de sa déclaration à la fin du bloc où il est déclaré.

    Pour un VLA, l'espace mémoire ne peut être alloué qu'au début de sa durée de vie (il faut bien connaitre sa taille pour le créer) et je pense que c'est également vrai pour les autres (pourquoi en serait-il autrement ?)

  14. #14
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Que la pile bouge ou non au sein d'un tour d'un même tour de boucle importe peu en C.
    Cela t'importe peu, mais j'imagine que si la pile bouge à chaque fois que tu entres dans un bloc (autre que fonction), tu te poserais des questions niveau performances...

    Si les variables sont effectivement poussées sur la pile des qu'on rentre dans un bloc j'imagine qu'au niveau de l'ABI ils ont prévu un truc pour dire de combien la pile va devoir diminuer lorsqu'on sort du bloc.

    Pour des variables comme les tableaux de taille dynamique du c99, il n'y a pas d'autres moyens que de "bouger" la pile en plein milieu de l'exécution de la fonction... Mais je ne pensais pas que cela soit fait dans d'autres cas.

  15. #15
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 388
    Points : 23 707
    Points
    23 707
    Par défaut
    Citation Envoyé par valefor Voir le message
    Cela t'importe peu, mais j'imagine que si la pile bouge à chaque fois que tu entres dans un bloc (autre que fonction), tu te poserais des questions niveau performances...
    Je pense que tu as mal lu les précédents commentaires.

  16. #16
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Tu fais référence aux ressources mémoire ?

    Je me posais la question en terme de temps. Combien de temps cela prend d'augmenter la taille de la pile... mais réflexion faite, c'est négligeable (c'est juste incrémenter un registre, il n'y a rien besoin de stoker d'autre sur la pile).

    Bon, du coup j’admets que ce n'est pas un si gros soucis que la pile joue au yoyo au sein même d'une fonction...

    Toutes ces histoires de taille de pile qui change en cours d'exécution d'une fonction me font penser à un post parallèle sur les goto

  17. #17
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    En gros, niveau machine, déplacer la pile, pour celle ci, ce n'est pas une masse à faire.
    Donc je pense que le topic est résolu (avant qu'on m'avertisse encore une fois)

    merci à tous pour vos réponses

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

Discussions similaires

  1. [ANT] affectation de variables dans une boucle
    Par dino_xrc dans le forum ANT
    Réponses: 6
    Dernier message: 17/12/2007, 19h47
  2. [VB.net] Declaration variable dans une boucle for
    Par nico10gbb dans le forum Windows Forms
    Réponses: 4
    Dernier message: 10/05/2006, 11h45
  3. Réponses: 6
    Dernier message: 17/03/2006, 12h23
  4. Réponses: 3
    Dernier message: 01/09/2005, 11h56
  5. [langage] incrementation de variable dans une boucle
    Par mimilou dans le forum Langage
    Réponses: 15
    Dernier message: 16/04/2004, 13h23

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