2011-11-09 5 views
8

Sto per eseguire il debug di qualcosa nella mia comunicazione boost socket asio. E ho trovato questo pezzo di codice all'interno della biblioteca ASIO (trovato in boost/ASIO/impl/linea write.hpp 169 (incrementare 1.47)):Boost :: asio cos'è questo strano stile di codifica?

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

ho già un sacco di anni di sviluppo C/C++ esperienza, ma mai e poi mai nella mia vita ho visto una specie di strana implementazione. Guarda lì, l'impostazione predefinita: l'etichetta dell'istruzione switch è all'interno del ciclo for.

Se ho capito bene, l'istruzione switch è "used" invece di goto, right (per i casi in cui start! = 1, goto default :)? È effettivamente un C/C++ valido rispetto allo standard? Cosa succede se per esempio messo

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

invece del ciclo for nel codice originale. "I" sarà indefinito nel caso in cui il salto venga eseguito al valore predefinito: etichetta? Certo, potrei usare un debugger qui, tuttavia questo sembra così sospetto per me, che penso che questo potrebbe produrre un comportamento diverso per diversi compilatori.

+1

Sembra che il ciclo 'for' sia usato come' goto'. Se il 'break' non viene eseguito, la successiva iterazione terminerà sicuramente prima dell'etichetta' default' a causa del 'return'. Roba piuttosto pelosa. –

risposta

8

Questo è un codice valido ben definito. Un switch è davvero un glorioso goto. Per un uso intelligente di questo costrutto, dai un'occhiata a Duff's device.

Per quanto riguarda il tuo for, non sarebbe legale. Un salto all'etichetta di un caso non può attraversare un'inizializzazione.

+0

Sei sicuro che sia davvero ben definito? Voglio dire interruttore Duff abusato invece di goto. Ha anche sostenuto che non sa se questo è buono o cattivo essere in grado di utilizzare interruttori come questo. – cgart

+0

Penso che si possa fare un argomento coerente che non è ben definito, ma penso che l'argomento più forte sia che è ben definito. È ben definito per 'goto', ed entrambi salgono allo stesso tipo di destinazione. (Cases e default sono etichette di istruzioni, proprio come gli obiettivi di 'goto'.) –