Apakah program yang tidak pernah menghentikan program C ++ yang valid?


15

Apakah program wajib diberhentikan? Dengan kata lain, apakah ada program yang berjalan selamanya, perilaku yang secara teknis tidak terdefinisi? Perhatikan ini bukan tentang loop kosong. Berbicara tentang program yang melakukan "hal-hal" (yaitu perilaku yang dapat diamati) selamanya.

Misalnya sesuatu seperti ini:

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

Ini lebih merupakan pertanyaan akademis, karena secara empiris semua penyusun waras akan menghasilkan kode yang diharapkan untuk jenis program di atas (dengan asumsi tentu saja tidak ada sumber lain dari UB). Dan ya, tentu saja ada banyak program yang tidak pernah berakhir (os, embeded, server). Namun standar kadang-kadang unik, jadi pertanyaannya.


Tangensial: banyak (beberapa?) Definisi "algoritma" mensyaratkan algoritma harus diakhiri , yaitu serangkaian operasi yang tidak pernah berakhir tidak dianggap sebagai algoritma.


Tangensial. Masalah penghentian menyatakan bahwa tidak ada algoritma untuk menentukan apakah program arbitrer selesai untuk input. Namun untuk program khusus ini karena tidak ada cabang yang mengarah keluar dari utama, kompiler dapat dengan mudah menentukan program tidak akan pernah berakhir. Namun ini tidak relevan karena pertanyaannya adalah pengacara bahasa.


Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Samuel Liew

Jawaban:


15

Tidak ada dalam standar C ++ yang mengharuskan program, atau utas apa pun, untuk diakhiri. Hal terdekat dari itu adalah [intro.progress] p1 , yang mengatakan

Implementasi dapat berasumsi bahwa utas pada akhirnya akan melakukan salah satu dari yang berikut:

  • mengakhiri,
  • melakukan panggilan ke fungsi I / O perpustakaan,
  • melakukan akses melalui glvalue yang mudah menguap, atau
  • melakukan operasi sinkronisasi atau operasi atom.

[  Catatan: Ini dimaksudkan untuk memungkinkan transformasi kompiler seperti penghapusan loop kosong, bahkan ketika penghentian tidak dapat dibuktikan. -  catatan akhir  ]

Selama ada beberapa perilaku yang dapat diamati, pada akhirnya, atau selama ia menghabiskan seluruh waktunya diblokir pada operasi I / O atau panggilan pustaka pemblokiran lainnya, ini tidak berlaku, dan program tersebut valid (dengan asumsi ia memenuhi semua kriteria validitas lainnya).


"operasi I / O atau panggilan perpustakaan pemblokiran lainnya" - Standar ini cukup jelas dan hanya mencantumkan operasi I / O. Mengapa Anda menambahkan "atau panggilan perpustakaan pemblokiran lainnya"? Juga, bahwa operasi I / O sudah termasuk dalam " beberapa perilaku yang dapat diamati" sebelumnya.
MSalters

1
@MSalters std::mutex::lock()adalah panggilan perpustakaan yang merupakan operasi sinkronisasi, berada di bawah peluru keempat. Jadi tidak benar bahwa hanya panggilan I / O yang disebutkan.
Igor Tandetnik

Jika terjebak pada input , tetapi tidak pernah mendapatkan apa pun, dapat diperdebatkan apakah itu dianggap dapat diamati.
Daniel H

4

Iya. Dari[intro.progress]

Implementasi dapat berasumsi bahwa utas pada akhirnya akan melakukan salah satu dari yang berikut:

  • mengakhiri,
  • melakukan panggilan ke fungsi I / O perpustakaan,
  • melakukan akses melalui glvalue yang mudah menguap, atau
  • melakukan operasi sinkronisasi atau operasi atom.

[ Catatan: Ini dimaksudkan untuk memungkinkan transformasi kompiler seperti penghapusan loop kosong, bahkan ketika penghentian tidak dapat dibuktikan. - catatan akhir ]


Saya percaya sedikit deskripsi yang menyatakan bahwa program I / O akan disarankan.
KamilCuk

Jadi selama get_inputdan put_outputfungsi dalam contoh OP "membuat panggilan ke fungsi I / O perpustakaan" program harus valid bahkan jika itu tidak berakhir?
Beberapa programmer dude

@Someprogrammerdude atau mengakses nilai atom atau volatil, Ya
Caleth

ingin tahu tentang standar pre c ++ 11, ketika tidak ada model memori saat ini.
bolov

1
compiler does not know- Ini tidak relevan. Kompiler mungkin tahu dan mungkin tidak tahu, dari sudut pandang lapisan bahasa - pertanyaannya adalah apakah valid, dalam hal apa pun.
KamilCuk
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.