2011-11-09 14 views
8

Estoy a punto de depurar algo dentro de mi Boost asio socket communication. Y ha encontrado este pedazo de código dentro de la biblioteca asio (que se encuentra en realce/ASIO/impl/línea write.hpp 169 (1,47 impulsar)):Boost :: asio ¿Qué es este tipo de estilo de codificación extraño?

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_)); 
    } 

ya tengo un montón de años de desarrollo en C/C++ experiencia, pero nunca en mi vida vi tal tipo de implementación extraña. Mire allí, el valor predeterminado: la etiqueta de la instrucción switch está dentro del ciclo for.

Si entiendo esto bien, la instrucción switch se "utiliza incorrectamente" en lugar de un goto, a la derecha (para los casos en que start! = 1, goto default :)? ¿Es en realidad un C/C++ válido con respecto al estándar? Qué pasará si pongo por ejemplo

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

en lugar del bucle en el código original. ¿No se definirá "i" en caso de que se ejecute el salto al valor predeterminado: ¿etiqueta? Seguro que podría usar un depurador aquí, sin embargo esto me parece tan sospechoso, que creo que esto podría producir un comportamiento diferente para los diferentes compiladores.

+1

Parece que el bucle 'for' se usa como' goto'. Si el 'break' no se ejecuta, la próxima iteración seguramente terminará antes de la etiqueta' default' debido al 'return'. Cosas bastante peludas. –

Respuesta

8

Este es un código válido y bien definido. Un switch realmente es un glorificado goto. Para algún uso inteligente de esta construcción, echa un vistazo a Duff's device.

En cuanto a su for, eso no sería legal. Un salto a una etiqueta de caja no puede cruzar una inicialización.

+0

¿Estás seguro de que esto está realmente bien definido? Me refiero a que Duff utilizó mal el interruptor en lugar de goto. Incluso argumentó que no sabe si esto es bueno o malo para poder usar interruptores como este. – cgart

+0

Creo que podrías argumentar coherentemente que no está bien definido, pero creo que el argumento más sólido es que está bien definido. Está bien definido para 'goto', y ambos saltan al mismo tipo de destino. (Los casos y el valor predeterminado son etiquetas de declaración, al igual que los objetivos de 'goto'.) –

Cuestiones relacionadas