Là một chương trình không bao giờ chấm dứt một chương trình C ++ hợp lệ?


15

Là một chương trình cần thiết để chấm dứt? Nói cách khác là một chương trình chạy mãi mãi về mặt kỹ thuật Hành vi không xác định? Lưu ý đây không phải là về các vòng lặp trống. Nói về các chương trình làm "công cụ" (tức là hành vi có thể quan sát) mãi mãi.

Ví dụ như một cái gì đó như thế này:

int main()
{
    while (true)
    {
        try
        {
            get_input(); // calls IO
            process();
            put_output(); // calls IO, has observable behavior

            // never break, exit, terminate, etc
        } catch(...)
        {
            // ignore all exceptions
            // don't (re)throw
            // never go out of loop
        }
    }
}

Đây là một câu hỏi học thuật nhiều hơn, vì theo kinh nghiệm, tất cả các trình biên dịch lành mạnh sẽ tạo mã dự kiến ​​cho loại chương trình trên (tất nhiên giả sử không có nguồn UB nào khác). Và vâng, tất nhiên có rất nhiều chương trình không bao giờ chấm dứt (os, nhúng, máy chủ). Tuy nhiên, tiêu chuẩn đôi khi kỳ quặc, do đó, câu hỏi.


Tiếp tuyến: nhiều định nghĩa (một số?) Của "thuật toán" yêu cầu thuật toán phải chấm dứt , tức là một loạt các hoạt động không bao giờ chấm dứt không được coi là một thuật toán.


Tiếp tuyến. Vấn đề tạm dừng nói rằng không thể tồn tại một thuật toán để xác định xem một chương trình tùy ý kết thúc cho một đầu vào. Tuy nhiên, đối với chương trình cụ thể này vì không có chi nhánh nào dẫn đến thoát khỏi chính, trình biên dịch có thể dễ dàng xác định chương trình sẽ không bao giờ kết thúc. Tuy nhiên điều này không liên quan vì câu hỏi là luật sư ngôn ngữ.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Samuel Liew

Câu trả lời:


15

Không có gì trong tiêu chuẩn C ++ yêu cầu chương trình, hoặc bất kỳ luồng đã cho nào, chấm dứt. Thứ gần nhất là [intro.proceed] p1 , cho biết

Việc thực hiện có thể cho rằng bất kỳ luồng nào cuối cùng cũng sẽ thực hiện một trong các thao tác sau:

  • chấm dứt,
  • thực hiện cuộc gọi đến chức năng I / O của thư viện
  • thực hiện truy cập thông qua một giá trị dễ bay hơi, hoặc
  • thực hiện một hoạt động đồng bộ hóa hoặc một hoạt động nguyên tử.

[  Lưu ý: Điều này nhằm cho phép các phép biến đổi trình biên dịch như loại bỏ các vòng lặp trống, ngay cả khi việc chấm dứt không thể được chứng minh. -  lưu ý cuối  ]

Miễn là có một số hành vi có thể quan sát được, cuối cùng, hoặc miễn là nó dành toàn bộ thời gian bị chặn cho một hoạt động I / O hoặc một cuộc gọi thư viện chặn khác, điều này không áp dụng và chương trình hợp lệ (giả sử nó đáp ứng tất cả các tiêu chí hợp lệ khác).


"Hoạt động I / O hoặc cuộc gọi thư viện chặn khác" - Tiêu chuẩn khá rõ ràng và chỉ liệt kê các hoạt động I / O. Tại sao bạn thêm "hoặc một cuộc gọi thư viện chặn" khác? Ngoài ra, thao tác I / O đó đã được bao gồm trong " một số hành vi có thể quan sát " trước đó của bạn .
MSalters

1
@MSalters std::mutex::lock()là một cuộc gọi thư viện là một hoạt động đồng bộ hóa, nằm dưới viên đạn thứ tư. Vì vậy, không đúng khi chỉ có các cuộc gọi I / O được đề cập.
Igor Tandetnik

Nếu nó bị kẹt ở đầu vào , nhưng không bao giờ nhận được bất kỳ, nó sẽ gây tranh cãi cho dù điều đó được tính là có thể quan sát được.
Daniel H

4

Đúng. Từ[intro.progress]

Việc thực hiện có thể cho rằng bất kỳ luồng nào cuối cùng cũng sẽ thực hiện một trong các thao tác sau:

  • chấm dứt,
  • thực hiện cuộc gọi đến chức năng I / O của thư viện
  • thực hiện truy cập thông qua một giá trị dễ bay hơi, hoặc
  • thực hiện một hoạt động đồng bộ hóa hoặc một hoạt động nguyên tử.

[ Lưu ý: Điều này nhằm cho phép các phép biến đổi trình biên dịch như loại bỏ các vòng lặp trống, ngay cả khi việc chấm dứt không thể được chứng minh. - lưu ý cuối ]


Tôi tin rằng một mô tả nhỏ nói rằng chương trình I / O sẽ được khuyến khích.
KamilCuk

Vì vậy, miễn là get_inputvà các put_outputchức năng trong ví dụ OP "thực hiện cuộc gọi đến chức năng I / O của thư viện", chương trình sẽ hợp lệ ngay cả khi nó không kết thúc?
Một số lập trình viên anh chàng

@Someprogrammerdude hoặc truy cập giá trị nguyên tử hoặc dễ bay hơi, Có
Caleth

tò mò về chuẩn pre c ++ 11, khi không có mô hình bộ nhớ hiện tại.
bolov

1
compiler does not know- Điều này không liên quan. Trình biên dịch có thể biết và có thể không biết, từ quan điểm của lớp ngôn ngữ - câu hỏi là nếu nó hợp lệ, trong mọi trường hợp.
KamilCuk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.