เป็นโปรแกรมที่ไม่เคยยกเลิกโปรแกรม C ++ ที่ถูกต้องหรือไม่?


15

จำเป็นต้องมีโปรแกรมหรือไม่ ในคำอื่น ๆ เป็นโปรแกรมที่ทำงานตลอดเวลาพฤติกรรมที่ไม่ได้กำหนดทางเทคนิค? โปรดทราบว่านี่ไม่เกี่ยวกับลูปที่ว่างเปล่า การพูดเกี่ยวกับโปรแกรมที่ทำ "สิ่ง" (เช่นพฤติกรรมที่สังเกตได้) ตลอดไป

เช่นบางสิ่งเช่นนี้

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
        }
    }
}

นี่เป็นคำถามเชิงวิชาการมากกว่าเนื่องจากผู้รวบรวมสติทั้งหมดจะสร้างโค้ดที่คาดหวังสำหรับโปรแกรมประเภทข้างต้น (สมมติว่าไม่มีแหล่งอื่นของ UB) และแน่นอนว่ามีโปรแกรมมากมายที่ไม่เคยหยุดทำงาน (ระบบปฏิบัติการ, เซิร์ฟเวอร์, เซิร์ฟเวอร์) อย่างไรก็ตามมาตรฐานบางครั้งก็แปลก


แทนเจนต์: คำจำกัดความจำนวนมาก (บาง?) ของ "อัลกอริทึม" ต้องการให้อัลกอริทึมต้องยุติเช่นชุดของการดำเนินการที่ไม่เคยยุติจะไม่ถือว่าเป็นอัลกอริทึม


สัมผัสวง ปัญหาการหยุดชะงักระบุว่าไม่มีอัลกอริทึมที่มีอยู่เพื่อตรวจสอบว่าโปรแกรมโดยพลการเสร็จสิ้นการป้อนข้อมูล อย่างไรก็ตามสำหรับโปรแกรมนี้โดยเฉพาะเนื่องจากไม่มีสาขาที่นำไปสู่การออกจากตัวหลักคอมไพเลอร์สามารถระบุได้อย่างง่ายดายว่าโปรแกรมจะไม่มีวันสิ้นสุด อย่างไรก็ตามเรื่องนี้ไม่เกี่ยวข้องเนื่องจากคำถามคือทนายความภาษา


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
ซามูเอล Liew

คำตอบ:


15

ไม่มีสิ่งใดในมาตรฐาน C ++ ที่ต้องการให้โปรแกรมหรือเธรดที่กำหนดใด ๆ ยุติการทำงาน สิ่งที่ใกล้เคียงที่สุดนั่นคือ[intro.progress] p1ซึ่งบอกว่า

การนำไปใช้อาจสันนิษฐานว่าเธรดใด ๆ จะทำอย่างใดอย่างหนึ่งต่อไปนี้:

  • ยกเลิก
  • โทรไปยังฟังก์ชั่นไลบรารี I / O
  • ทำการเข้าถึงผ่าน glvalue ที่ระเหยได้หรือ
  • ดำเนินการประสานหรือการดำเนินการปรมาณู

[  หมายเหตุ:นี่มีวัตถุประสงค์เพื่อให้การแปลงคอมไพเลอร์เช่นการลบลูปที่ว่างเปล่าแม้ว่าจะไม่สามารถพิสูจน์ได้ว่าการเลิกจ้าง -  บันทึกท้าย  ]

ตราบใดที่มีบางพฤติกรรมที่สังเกตได้ในที่สุดหรือตราบเท่าที่มันใช้เวลาตลอดเวลาของบล็อกในการดำเนินการ I / O หรืออื่นโทรห้องสมุดบล็อกนี้ไม่ได้นำไปใช้และโปรแกรมจะถูกต้อง (สมมติว่ามันตรงตาม เกณฑ์ความถูกต้องอื่น ๆ )


"การดำเนินการ I / O หรือการปิดกั้นการเรียกไลบรารีอื่น" - มาตรฐานค่อนข้างชัดเจนและแสดงรายการการดำเนินการ I / O เท่านั้น เหตุใดคุณจึงเพิ่ม "หรือการบล็อกการโทรเข้าห้องสมุดอื่น" นอกจากนี้ที่ I / O การทำงานรวมอยู่ในก่อนหน้านี้ของคุณ " บางพฤติกรรมที่สังเกตได้"
MSalters

1
@MSalters std::mutex::lock()เป็นการเรียกไลบรารีที่เป็นการดำเนินการซิงโครไนซ์โดยอยู่ภายใต้หัวข้อย่อยที่สี่ ดังนั้นจึงไม่เป็นความจริงที่มีการกล่าวถึงเฉพาะการโทร I / O
Igor Tandetnik

หากมันค้างอยู่ที่อินพุตแต่ไม่เคยได้รับอะไรเลยก็เป็นที่ถกเถียงกันอยู่ว่ามันนับเป็นสิ่งที่สังเกตได้หรือไม่
Daniel H

4

ใช่. จาก[intro.progress]

การนำไปใช้อาจสันนิษฐานว่าเธรดใด ๆ จะทำอย่างใดอย่างหนึ่งต่อไปนี้:

  • ยกเลิก
  • โทรไปยังฟังก์ชั่นไลบรารี I / O
  • ทำการเข้าถึงผ่าน glvalue ที่ระเหยได้หรือ
  • ดำเนินการประสานหรือการดำเนินการปรมาณู

[ หมายเหตุ:นี่มีวัตถุประสงค์เพื่อให้การแปลงคอมไพเลอร์เช่นการลบลูปที่ว่างเปล่าแม้ว่าจะไม่สามารถพิสูจน์ได้ว่าการเลิกจ้าง - บันทึกท้าย ]


ฉันเชื่อว่ามีคำอธิบายเล็กน้อยที่ระบุว่าโปรแกรม I / O จะแนะนำให้เลือก
KamilCuk

ดังนั้นตราบใดที่get_inputและput_outputฟังก์ชั่นในตัวอย่าง OPs "ทำการเรียกไปยังฟังก์ชันไลบรารี I / O" โปรแกรมควรจะถูกต้องแม้ว่ามันจะไม่ยุติ
โปรแกรมเมอร์บางคนเพื่อน

@Someprogrammerdude หรือเข้าถึงค่าความผันผวนหรือปรมาณูใช่
Caleth

อยากรู้เกี่ยวกับมาตรฐาน c ++ 11 ก่อนเมื่อไม่มีโมเดลหน่วยความจำปัจจุบัน
bolov

1
compiler does not know- สิ่งนี้ไม่เกี่ยวข้อง คอมไพเลอร์อาจรู้และอาจไม่ทราบจากมุมมองของเลเยอร์ภาษา - คำถามคือถ้ามันถูกต้องในทุกกรณี
KamilCuk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.