2011-11-09 38 views
8

我即将在我的boost asio套接字通信中调试一些东西。发现这段代码的ASIO库的内部(在升压发现/ ASIO/IMPL/write.hpp线169(提高1.47)):Boost :: asio这种奇怪的编码风格是什么?

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

我已经很多年C/C++开发经验,但从来没有在我的生活中看到过这种奇怪的实现。看那里,switch语句的默认:标签在for循环中。

如果我理解这个权利,那么switch语句是“误用”而不是goto,对(对于start!= 1,goto default :)的情况? 对于标准,它实际上是一个有效的C/C++吗? 如果我例如把

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

,而不是为循环原代码,会发生什么。如果在执行跳转到默认值的情况下将“未定义”:标签?当然我可以在这里使用调试器,但是这对我来说似乎很可疑,我认为这可能会对不同的编译器产生不同的行为。

+1

似乎'for'循环本身被用作'goto'。如果'break'没有被执行,下一次迭代肯定会在'default'标签之前因'return'而终止。相当多毛的东西。 –

回答

8

这是明确定义的有效代码。 A switch确实是一个荣耀goto。对于这个构造的一些聪明的使用,看看Duff's device

至于你的for,这将是不合法的。跳转到案例标签不能跨越初始化。

+0

你确定这个确定吗?我的意思是达夫滥用开关而不是转到。他甚至争辩说,他不知道这样做是好还是坏,以便能够使用这样的开关。 – cgart

+0

我认为你可以提出一个连贯的论点,认为它没有明确定义,但我认为更强有力的论点是它是明确的。它为goto定义的很好,并且它们都跳转到相同类型的目的地。 (案例和默认是声明标签,就像'goto'的目标一样。) –

相关问题