36 votes

Comment une variable peut-elle être utilisée lorsque sa définition est ignorée?

Dans mon esprit, toujours, de la définition des moyens d'allocation de stockage.

Dans le code suivant, int i alloue un 4 octets (généralement) de stockage sur la pile de programme et de le lier à l' i, et i = 3 assigne 3 de stockage. Mais à cause de l' goto, la définition est annulée, ce qui signifie qu'il n'est pas de stockage alloué pour i.

J'ai entendu dire que les variables locales sont affectés soit à l'entrée de la fonction (f() dans ce cas) où ils résident, ou au point de définition.

Mais de toute façon, comment peut - i être utilisée tant qu'elle n'est pas encore définie (pas de stockage à tous)? D'où vient la valeur de trois attribué lors de l'exécution d' i = 3?

void f()
{
    goto label;
    int i;

label:
    i = 3;
    cout << i << endl; //prints 3 successfully
}

44voto

Filip Roséen - refp Points 24995

Longue histoire courte; goto sera le résultat est un moteur d'exécution saut, définition de la variable/déclaration entraînera l'allocation du stockage, de la compilation.

Le compilateur va voir et de décider de combien de stockage pour l'allouer à un int, il va également faire en sorte que ce stockage alloué sera défini en 3 lors de "frapper" i = 3;.

Cet emplacement de la mémoire seront là, même si il y a un goto au début de votre fonction, avant la déclaration/définition, tout comme dans votre exemple.


Très bête simile

Si je place un journal sur le sol et mon ami s'exécute (yeux fermés) et saute par-dessus, le journal sera toujours là, même si il n'a pas vu ou ressenti.

Il est réaliste de dire qu'il pourrait tourner autour (au plus tard) et d'y mettre le feu, si il le voulait. Son saut n'en fait pas un journal comme par magie disparaître.

16voto

NPE Points 169956

Votre code est bien. La variable vie partout où elle allait vivre a l' goto pas été là.

Notez qu'il existe des situations où vous ne pouvez pas sauter par-dessus une déclaration:

C++11 6.7 Déclaration [stmt.dcl]

3 Il est possible de transférer en un bloc, mais pas d'une manière qui contourne les déclarations à l'initialisation. Un programme de sauts à partir d'un point où une variable automatique de la durée de stockage n'est pas dans le champ d'application à un point où il est dans la portée est mal formé, à moins que la variable est de type scalaire, le type de classe avec un trivial par défaut constructeur et d'un trivial destructeur, un cv qualifiés version de l'un de ces types, ou un tableau de l'un des types précédents et est déclarée sans un initialiseur (8.5). [ Exemple:

void f()
{
    // ...
    goto lx;    // ill-formed: jump into scope of `a'
    // ...
ly:
    X a = 1;
    // ...
lx:
    goto ly;    // ok, jump implies destructor
                // call for `a' followed by construction
                // again immediately following label ly
}

fin de l'exemple ]

9voto

dasblinkenlight Points 264350

Les définitions ne sont pas de code exécutable. Ils sont tout simplement les instructions pour le compilateur, lui permettant de connaître la taille et le type de la variable. En ce sens, la définition n'est pas court-circuité par l' goto déclaration.

Si vous utilisez une classe avec un constructeur plutôt qu'un int, l'appel du constructeur serait court-circuité par l' goto, mais l'espace de stockage serait affectée de toute façon. L'instance de classe resterait pas initialisés, cependant, afin de l'utiliser avant de sa définition/initialisation de la ligne obtient le contrôle est une erreur.

8voto

Björn Pollex Points 41424

Dans mon esprit, toujours, définition signifie allocation de stockage.

Ce n'est pas correct Le stockage de la variable est réservé par le compilateur lorsqu'il crée la structure de pile pour la fonction. Le goto contourne simplement l'initialisation. Puisque vous attribuez une valeur avant l'impression, tout va bien.

2voto

Nawaz Points 148870

Le contrôle de flux n'a rien à voir avec la variable de stockage qui est réservé au moment de la compilation par le compilateur.

L' goto de résultat les effets de la dynamique de l'initialisation de l'objet. Pour les types intégrés et la GOUSSE types, il n'a pas d'importance, car elles peuvent rester non initialisée. Cependant, pour les non-POD types, cela aurait pour conséquence d'erreur de compilation. Voir, par exemple, ce

struct A{ A(){} };  //it is a non-POD type

void f()
{
    goto label;

    A a;     //error - you cannot skip this!

label:
    return;
}

Erreur:

prog.cpp: In function ‘void f()':
prog.cpp:8: error: jump to label ‘label'
prog.cpp:5: error:   from here
prog.cpp:6: error:   crosses initialization of ‘A a'

Voir ici : http://ideone.com/p6kau

Dans cet exemple, A est un non-POD type parce qu'il a définie par l'utilisateur constructeur, ce qui signifie que l'objet doit être dynamiquement initialisé, mais depuis l' goto instruction tente d'ignorer cela, le compilateur génère une erreur, comme il se doit.

Veuillez noter que les objets de seulement intégré dans les types et les types POD peut rester non initialisée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X