2010-11-25 5 views
7
cas

Eh bien, ce n'est pas vraiment une question ..Déclaration de variables à l'intérieur de l'interrupteur C/

Je viens de temps en temps découvert qu'il ya une façon intéressante de déclarer des variables locales à l'intérieur d'un bloc commutateur/boîtier. Au lieu d'utiliser des accolades dans chaque bloc de cas, vous pouvez écrire:

switch (action) { 
    int res; 
    int value; 
case ACTION_OPEN: 
    res = open(...); 
    ... 
    break; 
case ... 
} 

Alors, je me demande ce que les compilateurs C/C++ en plus de soutien gcc cette construction? Cela ressemble à une erreur commune. Tous les commentaires sur cette construction sont les bienvenus!

+0

+1, juste pour savoir si cela est légal C++ ou un accident du compilateur. Cela pourrait être utile si c'est autorisé. –

+0

Un moyen plus simple est d'arrêter d'utiliser les compilateurs C qui sont périmés depuis 11+ ans. –

+0

Encore, sauf pour la chute occasionnelle, je préfère toujours les accolades à l'intérieur de chaque bloc de cas pour une portée plus locale. C'est une question de goût. – stefaanv

Répondre

1

Tout compilateur C ou C++ conforme aux normes le permettra. Même un ancien compilateur C (pré-ISO C99) C le permettra, mais seulement parce que les déclarations de variables sont au début d'une instruction block/compound (notée {}).

Notez que ce qui suit un switch est presque une déclaration normale, à l'exception de la possibilité d'étiquettes de cas:

int main(int argc, char* argv[]) 
{ 
    switch (argc) 
     default: 
     puts("Hello, world!"); 

    return 0; 
} 

Ainsi, en ANSI C89, ce sont les accolades qui font la magie ici.

3

Le corps du commutateur est simplement une instruction normale (dans votre cas une instruction composée, ressemblant à { ... }) qui peut contenir n'importe quelle connerie. Y compris les étiquettes de cas. Cette philosophie de commutation est abusée par Duffs device.

Beaucoup de gens ne se rendent pas compte que même quelque chose comme switch(0) ; est une déclaration valide (au lieu d'avoir une instruction composée, il a une instruction null comme corps), bien que tout à fait inutile.

+0

Cela n'a rien à voir avec les déclarations de variables. Duff n'a pas déclaré de variables dans son instruction 'switch', car les compilateurs C de son jour auraient nécessité des blocs supplémentaires (qui auraient probablement été traduits en instructions push/pop). –

+3

@larsmans L'appareil de Duff n'a rien à voir avec les déclarations de variables, mais il a tout à voir avec l'abus de la structure de commutateur employée par C et C++. En particulier, ces étiquettes de cas ne sont pas vraiment «spéciales» mais juste des étiquettes de saut. Une fois que cela est connu, il n'est pas surprenant du tout que vous puissiez mettre des déclarations avant les étiquettes de cas dans un corps de commutateur. –

-1

Je pense que C99 permet de déclarer la variable (presque) partout où vous voulez à l'intérieur des blocs, donc ce comportement devrait être considéré comme légal .. et je ne vois pas de risque réel puisqu'il s'agit juste d'une déclaration.

0

Strictement parlé, le cas que vous présentez avec int est autorisé dans les trois langues, mais pour des raisons différentes. Dans tous les cas (pour C89) et dans tous les cas sauf un (pour C99), C permet de sauter la définition de n'importe quelle variable locale (arithmétique, struct, union, tableau ...). Les exceptions pour C99 sont des tableaux de longueur variable. C++ autorise cela uniquement pour les types de données qui n'ont pas de constructeur ou de destructeur, souvent appelé POD.

Donc, si vous avez un type T au lieu de int dans votre exemple dans ce C89 est toujours valide, et en C99 et C++, il dépend du type T si oui ou non cela est correct. Dans tous les cas, tout cela conduit facilement à des variables non initialisées, mieux vaut ne pas le faire si vous pouvez l'éviter.

Questions connexes