2011-11-09 1 views
8

Je suis sur le point de déboguer quelque chose dans ma communication d'asio socket boost. Et trouvé ce morceau de code à l'intérieur de la bibliothèque asio (dans la ligne boost/ASIO/impl/write.hpp 169 (stimuler 1,47)):Boost :: asio quel est ce genre de code étrange?

switch (start) 
    { 
    case 1: 
    buffers_.prepare(this->check_for_completion(ec, total_transferred_)); 
    for (;;) 
    { 
     stream_.async_write_some(buffers_, 
      BOOST_ASIO_MOVE_CAST(write_op)(*this)); 
     return; 
    default: 
     total_transferred_ += bytes_transferred; 
     buffers_.consume(bytes_transferred); 
     buffers_.prepare(this->check_for_completion(ec, total_transferred_)); 
     if ((!ec && bytes_transferred == 0) 
      || buffers_.begin() == buffers_.end()) 
     break; 
    } 

    handler_(ec, static_cast<const std::size_t&>(total_transferred_)); 
    } 

J'ai déjà beaucoup d'années de développement C/C++ expérience, mais jamais dans ma vie j'ai vu une telle mise en œuvre étrange. Regardez là, l'étiquette par défaut de l'instruction switch est dans la boucle for.

Si je comprends bien ce droit, alors l'instruction switch est "mal utilisée" au lieu d'un goto, à droite (pour les cas où start! = 1, goto default :)? Est-ce réellement un C/C++ valide par rapport à la norme? Qu'est-ce qui se passera si je par exemple mis

for(int i=0; i < 10; i++) 

au lieu de la boucle dans le code d'origine. Est-ce que "i" sera indéfini dans le cas où le saut est effectué par défaut: label? Bien sûr, je pourrais utiliser un débogueur ici, même si cela me semble si suspect, que je pense que cela pourrait produire un comportement différent pour les différents compilateurs.

+1

On dirait que la boucle 'for' elle-même est utilisée comme' goto'. Si le 'break' n'est pas exécuté, l'itération suivante se terminera sûrement avant l'étiquette' default' en raison de 'return'. Des trucs assez poilus. –

Répondre

8

Il s'agit d'un code valide et bien défini. Un switch est vraiment un glorifié goto. Pour une utilisation intelligente de cette construction, jetez un oeil à Duff's device.

Quant à votre for, ce ne serait pas légal. Un saut vers une étiquette de cas ne peut pas traverser une initialisation.

+0

Etes-vous sûr que c'est vraiment bien défini? Je veux dire que Duff a mal utilisé le commutateur au lieu de goto. Il a même fait valoir qu'il ne sait pas si c'est bon ou mauvais de pouvoir utiliser des commutateurs comme celui-ci. – cgart

+0

Je pense que vous pourriez faire un argument cohérent que ce n'est pas bien défini, mais je pense que l'argument le plus fort est qu'il est bien défini. C'est bien défini pour 'goto', et ils vont tous deux au même type de destination. (Les cas et les valeurs par défaut sont des étiquettes d'instructions, tout comme les cibles de 'goto'.) –