Ok. Juste pour clarifier, cela n'a strictement rien à voir avec la déclaration. Il s'agit uniquement de "sauter par-dessus l'initialisation" (ISO C++ '03 6.7/3).
De nombreux messages ici ont mentionné que le fait de sauter par-dessus la déclaration peut avoir pour conséquence que la variable "n'est pas déclarée". Ceci n'est pas vrai. Un objet POD peut être déclaré sans initialisateur mais il aura une valeur indéterminée. Par exemple :
switch (i)
{
case 0:
int j; // 'j' has indeterminate value
j = 0; // 'j' set (not initialized) to 0, but this statement
// is jumped when 'i == 1'
break;
case 1:
++j; // 'j' is in scope here - but it has an indeterminate value
break;
}
Lorsque l'objet est un non-POD ou un agrégat, le compilateur ajoute implicitement un initialisateur, et il n'est donc pas possible de sauter par-dessus une telle déclaration :
class A {
public:
A ();
};
switch (i) // Error - jumping over initialization of 'A'
{
case 0:
A j; // Compiler implicitly calls default constructor
break;
case 1:
break;
}
Cette limitation ne se limite pas à l'énoncé du commutateur. L'utilisation de 'goto' pour sauter par-dessus une initialisation est également une erreur :
goto LABEL; // Error jumping over initialization
int j = 0;
LABEL:
;
Il s'agit d'une différence entre le C++ et le C. En C, ce n'est pas une erreur de sauter l'initialisation.
Comme d'autres l'ont mentionné, la solution consiste à ajouter un bloc imbriqué afin que la durée de vie de la variable soit limitée à l'étiquette du cas individuel.
10 votes
Pour une explication basée sur la grammaire C BNF, voir stackoverflow.com/questions/1180550/weird-switch-error-in-obj-c/
0 votes
Voici une très bonne lecture à propos des déclarations d'interrupteurs et des étiquettes (ABC :) en général.
5 votes
Je dirais "Pourquoi les variables ne peuvent-elles pas être initialisées dans une instruction switch plutôt que déclarées", puisque la simple déclaration de la variable ne me donne qu'un avertissement dans MSVC.
3 votes
Si vous placez tout ce qui se trouve dans l'étiquette de la casse entre accolades { }, cela fonctionnera.