web-dev-qa-db-fra.com

Déclaration de variables dans une instruction switch

J'ai vu quelques réponses à ce problème, et je comprends - vous ne pouvez pas déclarer et affecter des variables dans un switch. Mais je me demande si ce qui suit est correct pour lancer une erreur disant

erreur: expression attendue avant 'int'

Code:

switch (i) {
    case 0:
        int j = 1;
        break;
}

Pourquoi placer un appel à NSLog() avant qu'il n'entraîne aucune erreur?

switch (i) {
    case 0:
        NSLog(@"wtf");
        int j = 1;
        break;
}
113
dizy

En fait, vous pouvez déclarer des variables dans un commutateur si vous le faites selon la syntaxe du langage. Vous obtenez une erreur car "case 0: "est une étiquette, et en C, il est illégal d'avoir une déclaration comme première instruction après une étiquette - notez que le compilateur attend une expression , comme un appel de méthode, une affectation normale, etc. (Bizarre que cela puisse être, c'est la règle.)

Lorsque vous placez le NSLog () en premier, vous avez évité cette limitation. Vous pouvez placer le contenu d'un cas entre accolades {} pour introduire un bloc de portée ou vous pouvez déplacer la déclaration de variable en dehors du commutateur. Ce que vous choisissez est une question de préférence personnelle. Sachez simplement qu'une variable déclarée entre accolades {} n'est valide que dans cette étendue, donc tout autre code qui l'utilise doit également apparaître entre ces accolades.


Modifier:

Soit dit en passant, cette bizarrerie n'est pas aussi rare que vous ne le pensez. En C et Java, il est également illégal d'utiliser une déclaration de variable locale comme instruction solitaire (signifiant "non entouré d'accolades) dans un pour , tandis que , ou boucle , ou même dans if et else clauses (en fait, cela est couvert dans le casse-tête # 55 de "Java Puzzlers" , ce que je recommande fortement.) Je pense que nous n'écrivons généralement pas de telles erreurs pour commencer car cela n'a pas de sens de déclarer une variable comme seule instruction dans de tels contextes. Avec switch / case constructs, cependant, certaines personnes omettent les accolades puisque le l'instruction break est l'instruction critique pour le flux de contrôle.

Pour voir les ajustements du compilateur, copiez cet horrible extrait inutile dans votre code C (Objective-):

if (1)
    int i;
else
    int i;
for (int answer = 1; answer <= 42; answer ++)
    int i;
while (1)
    int i;
do
    int i;
while (1);

Encore une autre raison de toujours utiliser des accolades {} pour délimiter le corps de ces constructions. :-)

139
Quinn Taylor

J'ai rencontré ce problème auparavant, et la conclusion était que vous venez de mettre le code dans un bloc.

switch (i) {
case 0:
    {
        int j = 1;
        break;
    }
}
46
newacct

Une autre solution simple que j'utilise consiste à ajouter une expression vide (point-virgule) avant la déclaration. Cela évite de limiter la portée de la variable à un bloc de code (ou d'avoir des instructions case avec des blocs de code et d'autres sans).

switch (i) {
    case 0:;
        int j = 1;
        break;
}
3
Joel