我即将在我的boost asio socket通信中调试一些东西。并在asio库中找到了这段代码(在boost / asio / impl / write.hpp第169行(boost 1.47)中找到):
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++)
而不是原始代码中的for循环。如果跳转执行到默认值,“i”是否会被定义:标签?当然我可能会在这里使用调试器,但这对我来说似乎很可疑,我认为这可能会为不同的编译器产生不同的行为。
答案 0 :(得分:8)
这是定义良好的有效代码。 switch
确实是一个荣耀的goto
。要巧妙地使用此构造,请查看Duff's device。
至于你的for
,这是不合法的。跳转到案例标签不能跨越初始化。
答案 1 :(得分:2)
它似乎是Duff's device的一个版本。