“les croix de l'initialisation de la variable” seulement lorsque l'initialisation est combiné avec de la déclaration de
J'ai lu cette question sur le "saut de cas étiquette" erreur, mais j'ai encore quelques questions. J'utilise g++ 4.7 sur Ubuntu 12.04.
Ce code donne une erreur:
int main() {
int foo = 1;
switch(foo) {
case 1:
int i = 0;
i++;
break;
case 2:
i++;
break;
}
}
L'erreur est
jump-to-case-label.cpp: In function ‘int main()’:
jump-to-case-label.cpp:8:8: error: jump to case label [-fpermissive]
jump-to-case-label.cpp:5:9: error: crosses initialization of ‘int i’
Toutefois, ce code compile fine,
int main() {
int foo = 1;
switch(foo) {
case 1:
int i;
i = 0;
i++;
break;
case 2:
i++;
break;
}
}
Est le deuxième code, moins dangereux que le premier? Je suis confus quant à pourquoi g++ permet.
Deuxièmement, le correctif de ce problème est à la portée de la variable initialisée. Si le initialisé la variable est un objet de grande taille, et l'instruction switch est dans une boucle while, ne sera pas le constructeur et le destructeur sera appelée à chaque fois que le champ d'application est entré et de gauche, provoquant une diminution de l'efficacité? Ou va le compilateur d'optimiser cette suite?
i
n'a pas encore été déclaré!(Le "secondaire" message d'erreur semble plus pertinente à la question.)
Pourrait le downvoter veuillez expliquer leur downvote?
Pourquoi pensez-vous
i
n'a pas été déclarée? Il est clairement défini dans le bloc sur la ligne après le case 1:
étiquette. Le break
consolidés ne pas comme par magie diviser le bloc dans des champs d'application différents. Il n'aurait pas de sens de le faire, car ils peuvent être conditionnelle exécutée que si le programmeur choisit de le faire.
OriginalL'auteur gsingh2011 | 2012-10-20
Vous devez vous connecter pour publier un commentaire.
Sauter passé l'initialisation d'un objet, même si l'objet est de type
int
, est toujours un comportement indéfini. Notez que leswitch
-déclaration déclaration n'est rien de spécial: C'est juste une déclaration et les gens ont [ab]utilisés de cette manière intéressante, par exemple, pour Duff de l'Appareil. La seule chose qui est spécial à l'intérieur de l'énoncé, c'est que les étiquettes peuvent prendre la formedefault:
etcase <const-integer-expr>:
.La déclaration
int i;
est une définition de la variable, mais pas de l'initialisation. Ainsi, pas d'initialisation d'une variable est franchi. Il n'y a pas de plus grand problème de saut delà de cette définition qu'il y a en premier lieu. Bien sûr, la valeur est affectée en sautant àcase 1:
et non pas en sautant àcase 2:
mais ce n'est pas différent de ce qui se passe dans le code de l'extérieur deswitch
-déclarations si seulement les gens définissent des variables.foo = 2
il compile.Bien sûr, il compile: le code est bien formé et seulement les résultats dans un comportement indéfini lorsque le saut à la
case 2:
étiquette. Il doit cracher un avertissement, si, sifoo == 2
. Juste repéré pourquoi il n'a pas d'avertir: il n'a pas prévenu parce que la variable est défini mais pas initialisé. Une phase d'initialisation ressembleraitint i = 0;
.OriginalL'auteur Dietmar Kühl
Au premier abord, le compilateur décide comment il va ouvrir
switch
de code assembleur. Peut-êtreif
ou peut-être la table commegoto
. Aussi, si vous écrivez de la variable d'initialisation de l'ensemble de la déclaration, le compilateur vous dit que c'esterror
. Dans un autre cas, il serawarning
(compilateur vous met en garde, mais ne résiste pas à vous). Donc, vous pouvez vous protéger. Seulement il optimise les options du compilateur, oùwarnings
il seraerrors
.Et de travailler correctement avec des variables dans le
switch
, vous devez préciser leur champ d'application. Par exemple:PS. Pour c++, switch, c'est l'enfer.
À Partir De C++11:
De gcc diagnostic pragmas:
PSS. Le compilateur sait que dans le morceau de code de votre variable non initialisée. Quoi qu'il en été
static C/C++ analysis
(Par exemple, pour gratuitcppcheck
) de vous montrer le problème.Bien sûr, que pensez-vous de Martin Fowler et le polymorphisme?
Je pense que le fractionnement de la logique dans 20 classes chacune avec salle de méthode pour éviter une instruction switch va me garder utilisé un long temps de fixation de leur code une fois qu'ils sont licenciés.
J'ai parlé de l'abus des interrupteurs.
OriginalL'auteur Ruu
De tourner sur des mises en garde (Mur) dans le deuxième cas donne:
Sauter passé d'initialisation est une erreur, mais le compilateur n'essayez pas de deviner que vous sur les variables non initialisées.
OriginalL'auteur stark
De l'initialisation d'une variable à l'intérieur de l'interrupteur provoque cette erreur. Cela se produit en raison d'un problème d'autorisation. Essayez de l'initialisation de la variable à l'extérieur de l'interrupteur et assigner des valeurs à l'intérieur de l'interrupteur.
Même question s'applique à C++ threads.
OriginalL'auteur Choxmi