2011-11-09 30 views
8

Tôi sắp sửa gỡ lỗi gì đó trong giao tiếp socket asio tăng cường của mình. Và tìm thấy đoạn mã này bên trong thư viện ASIO (tìm thấy trong tăng/ASIO/impl/dòng write.hpp 169 (tăng 1,47)):Boost :: asio kiểu mã lạ này là gì?

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

Tôi đã có rất nhiều năm của C/C++ phát triển kinh nghiệm, nhưng chưa bao giờ trong đời tôi thấy một loại thực hiện kì quặc như vậy. Nhìn ở đó, mặc định: nhãn của câu lệnh switch nằm trong vòng lặp for.

Nếu tôi hiểu điều này đúng, thì câu lệnh chuyển đổi là "lạm dụng" thay vì một goto, đúng (đối với trường hợp bắt đầu! = 1, goto mặc định :)? Nó thực sự là một C/C++ hợp lệ đối với tiêu chuẩn? Điều gì sẽ xảy ra nếu tôi ví dụ: đặt

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

thay vì cho vòng lặp trong mã ban đầu. "I" sẽ không được xác định trong trường hợp khi nhảy được thực hiện theo mặc định: nhãn? Chắc chắn tôi có thể sử dụng một trình gỡ lỗi ở đây, tuy nhiên điều này có vẻ rất đáng ngờ đối với tôi, rằng tôi nghĩ rằng điều này có thể tạo ra hành vi khác nhau cho các trình biên dịch khác nhau.

+1

Dường như bản thân vòng lặp 'for' được sử dụng như một' goto'. Nếu 'break' không được thực hiện, thì lần lặp tiếp theo chắc chắn sẽ kết thúc trước nhãn' default' do 'return'. Khá lông. –

Trả lời

8

Đây là mã được xác định, hợp lệ. A switch thực sự là một vinh quang goto. Đối với một số sử dụng thông minh của cấu trúc này, hãy xem Duff's device.

Đối với số for của bạn, điều đó sẽ không hợp pháp. Nhảy đến một nhãn trường hợp không thể vượt qua một khởi tạo.

+0

Bạn có chắc chắn rằng điều này thực sự được xác định rõ? Tôi có nghĩa là Duff sử dụng sai chuyển đổi thay vì goto. Anh thậm chí còn lập luận rằng anh không biết liệu điều này là tốt hay xấu để có thể sử dụng các công tắc như thế này. – cgart

+0

Tôi nghĩ rằng bạn có thể đưa ra một lập luận chặt chẽ rằng nó không được xác định rõ ràng, nhưng tôi nghĩ rằng lập luận mạnh mẽ hơn là nó được xác định rõ ràng. Nó được định nghĩa rõ ràng cho 'goto', và cả hai đều nhảy đến cùng một loại đích. (Các trường hợp và mặc định là các nhãn câu lệnh, giống như các mục tiêu của 'goto'.) –