question sur static

question sur static - C++ - Programmation

Marsh Posté le 22-12-2010 à 15:59:42    

bonjour,
Il y a quelque chose que je ne comprend pas avec le mot clé "static".

 

Dans le cas où c'est utilisé dans un bloc de code (hors membre ou fonction de classe), il me semble que c'est une variable qui est initialisée au linkage du programme, soit avant même l'exécution, et que l'adresse est toujours la même.

 

Dans ce cas, il me semble aussi qu'il est possible de changer changer la valeur de cette variable, par exemple :

 
Code :
  1. static int a = 10;
  2. //du code
  3. a = 12; //'a' vaut maintenant 12

 

Or, avec un appel de fonction, ce n'est pas possible, la valeur est toujours la même...Par exemple :

Code :
  1. static int a = toto(); //toto() est une fonction qui renvoie un nombre entier aléatoire, ici par exemple c'est 10
  2. a = toto(); //ici, la fonction n'est même pas appelée, au débugger on ne rentre pas dedans.
 

Pourquoi est ce que c'est comme ça ? c'est pourtant là aussi une affectation de valeur ....c'est ça que je ne comprend pas.

 

Par ailleurs, est ce qu'une variable globale est "static" ? dans ce cas est ce que la déclarer en 'static' est redondant ?

 

merci par avance

Message cité 1 fois
Message édité par in_your_phion le 22-12-2010 à 16:00:05
Reply

Marsh Posté le 22-12-2010 à 15:59:42   

Reply

Marsh Posté le 22-12-2010 à 16:23:22    

Donne un exemple complet, parce que je ne constate pas ce dont tu te plains.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 22-12-2010 à 16:39:41    

Citation :

a = toto(); //ici, la fonction n'est même pas appelée, au débugger on ne rentre pas dedans.


Tu utilises a ensuite? Parce que sinon, ça peut juste être du à une optimisation de ton compilateur qui vire du code mort.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 22-12-2010 à 17:16:27    

in_your_phion a écrit :


Code :
  1. static int a = toto(); //toto() est une fonction qui renvoie un nombre entier aléatoire, ici par exemple c'est 10




Le compilateur risque d'avoir du mal à évaluer la valeur de a avant linkage, ce qui signifie que a est bien initialisé à l'exécution.
Ce code est très dangereux car à ma connaissance tu ne sais pas dans quel ordre les variables globales vont être initialisées, et donc si toto() utilise une autre variable globale, le résultat de l'initialisation n'est pas prévisible.

 
in_your_phion a écrit :


Par ailleurs, est ce qu'une variable globale est "static" ? dans ce cas est ce que la déclarer en 'static' est redondant ?


Non, static a ici le sens "visible uniquement dans le contexte" c'est à dire le fichier c compilé après passage du préprocesseur.
Cette variable n'est donc pas partagée entre deux fichiers c

Message cité 1 fois
Message édité par h3bus le 22-12-2010 à 17:18:21

---------------
sheep++
Reply

Marsh Posté le 22-12-2010 à 17:21:29    

h3bus a écrit :

Ce code est très dangereux car à ma connaissance tu ne sais pas dans quel ordre les variables globales vont être initialisées


 
Tres dangereux?
 
A l'interieur d'une unite de compilation, l'ordre est fixe par le langage: c'est l'ordre de definition.
 
Entre unites de compilation, l'ordre n'est pas defini par le langage.  Mais les implementations permettent souvent de le definir, au moins partiellement.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 22-12-2010 à 17:27:03    

Un Programmeur a écrit :


Entre unites de compilation, l'ordre n'est pas defini par le langage.  Mais les implementations permettent souvent de le definir, au moins partiellement.


Justement comment tu peux le définir lors d'une initialisation, si les variables globales sont partagé entre deux .c?


---------------
sheep++
Reply

Marsh Posté le 22-12-2010 à 18:56:22    

h3bus a écrit :


Justement comment tu peux le définir lors d'une initialisation, si les variables globales sont partagé entre deux .c?


 
Regarde dans la doc de l'implementation qui t'interesse si c'est possible (de memoire gcc le permet avec ses attributs).
 
Perso, j'ai tendance simplement a ne pas dependre de l'ordre d'initialisation entre unites de compilation.
 
Pour etre plus clair sur ma remarque: je trouve exagéré de qualifier en général l'initialisation dynamique de très dangereux simplement a cause du risque potentiel de dependance sur l'ordre d'initialisation entre unites de compilation.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 22-12-2010 à 21:32:56    

Bon je suis d'accord c'est exagéré, je dirais simplement que je le déconseille.
 
Mais ce n'est que mon avis.


---------------
sheep++
Reply

Marsh Posté le 28-12-2010 à 12:45:53    

Un Programmeur a écrit :

Donne un exemple complet, parce que je ne constate pas ce dont tu te plains.

 

hello, par exemple ce code :

 
Code :
  1. #include <iostream>
  2. using namespace std;
  3. int i=10;
  4. int toto() {
  5. return i++;
  6. }
  7. int main(void)
  8. {
  9. for (;;)
  10. {
  11.  static int val = toto();
  12.  cout << val << endl;
  13. }
  14. return 0;
  15. }
 

on ne passe qu'une seule fois dans la fonction toto(). Pourquoi ?


Message édité par in_your_phion le 28-12-2010 à 12:46:26
Reply

Marsh Posté le 28-12-2010 à 13:19:22    

Parce que tu ne modifie pas ta variable val.
Il n'y a que son initialisation mais elle n'est faite bien sûr qu'une seule fois.

Reply

Marsh Posté le 28-12-2010 à 13:19:22   

Reply

Marsh Posté le 28-12-2010 à 13:19:53    

Parce que val est statique donc son initialisation n'est faite qu'au premier passage dans la boucle.  Ce qui fait la différence avec ton premier message, c'est que dans celui-là tu avais une initialisation et une assignation.  Si tu avais une assignation dans la boucle, elle serait faite pour chaque passage (y compris le premier, donc pour celui-là tu aurais deux appels: un pour initialisation, un pour l'assignation.)


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 28-12-2010 à 19:23:55    

ok ... merci pour vos réponses!
 
Donc, si je comprend bien ceci créerait un appel de la fonction toto() à chaque itération de la boucle :
 

Code :
  1. #include <iostream>
  2. using namespace std;
  3. int i=10;
  4. int toto() {
  5. return i++;
  6. }
  7. int main(void)
  8. {
  9. for (;;)
  10. {
  11.   static int val; //val vaut ... 0 ?
  12.   val = toto();
  13.   cout << val << endl;
  14.   }
  15.  
  16.   return 0;
  17.   }

Reply

Marsh Posté le 28-12-2010 à 20:03:49    

Voilà exactement.  
Lors de ta déclaration, val contient une valeur non définie.


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 29-12-2010 à 10:52:59    

esox_ch a écrit :

Voilà exactement.  
Lors de ta déclaration, val contient une valeur non définie.


 
Les variables statiques sont initialisées à 0 si elles ne sont pas initialisées explicitement à une autre valeur.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 29-12-2010 à 20:29:15    

Autant pour moi :jap:
Question subsidiaire : Il y a une raison à ça? C'est bien pratique que ce soit comme ça, mais personnellement je trouverais ça bien pratique que ce soit comme ça aussi pour les autres variables :D


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 29-12-2010 à 20:47:40    

Une variable statique c'est une variable globale.  Au démarrage, l'OS va l'initialiser de toute façon (pour éviter de laisser filtrer des informations sur les autres process).  A mon avis, c'est donc venu gratuitement sans rien faire de spécial avec la première implémentation et les autres même sans support de l'OS ont suivit parce que c'était utile et utilisé et ça c'est retrouvé dans la norme.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 30-12-2010 à 17:56:26    

esox_ch a écrit :

Autant pour moi :jap:
Question subsidiaire : Il y a une raison à ça? C'est bien pratique que ce soit comme ça, mais personnellement je trouverais ça bien pratique que ce soit comme ça aussi pour les autres variables :D

J'ai eu un compilo C qui faisait ce type d'initialisation pour toute variable pas explicitement initialisée à la déclaration. C'était sur une station Dec/Ultrix. C'est trop sécurisant, ça donne de mauvaises habitudes. Je te dis pas la cata le jour ou le code a été recompilé sur station SUN/SUN OS ou il y avait pas ces initialisations par défaut :whistle:  
A+,

Message cité 1 fois
Message édité par gilou le 30-12-2010 à 17:57:39

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 30-12-2010 à 19:44:35    

gilou a écrit :

J'ai eu un compilo C qui faisait ce type d'initialisation pour toute variable pas explicitement initialisée à la déclaration. C'était sur une station Dec/Ultrix. C'est trop sécurisant, ça donne de mauvaises habitudes. Je te dis pas la cata le jour ou le code a été recompilé sur station SUN/SUN OS ou il y avait pas ces initialisations par défaut :whistle:  
A+,


+1, j'ai assisté à ça lors d'un examen pratique, aux études... Un camarade de bagne avait réalisé et testé son projet sous Windows avant de recompiler sous SunOS sans retester... Kaboom pour son examen :sweat:
 
Ca t'apprend à ne jamais te fier à ce genre de comportement et à être explicite.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed