Sampel perilaku terdefinisi terpendek dalam C ++ [ditutup]


8

Apa kode C ++ terpendek yang terbentuk dengan baik yang menunjukkan perilaku tidak terdefinisi?


1
Apa maksudmu "runnable"? Jika memiliki UB, tidak ada jaminan bisa dijalankan.
R. Martinho Fernandes

@ R. MartinhoFernandes baik, maksud saya itu dimulai.
Luchian Grigore

@LuchianGrigore yang sangat bergantung pada kompiler (versi).
rubenvb

1
Tentukan "pameran". Apakah perlu menunjukkan sesuatu? Atau cukupkah kondisi memori internal tidak ditentukan pada beberapa titik selama program?
Tuan Lister

Jawaban:


12
int main(){main;}

3.6.1 Fungsi utama [basic.start.main]

3 - [...] Fungsi utama tidak boleh digunakan dalam suatu program.

Sunting: ini bisa didiagnosis, jadi bukan UB.


int main(){for(;;);}

1.10 Eksekusi multi-utas dan data balapan [intro.multithread]

24 - Implementasi dapat mengasumsikan bahwa utas pada akhirnya akan melakukan salah satu dari yang berikut: - mengakhiri, - melakukan panggilan ke fungsi I / O perpustakaan, - mengakses atau memodifikasi objek yang mudah menguap, atau - melakukan operasi sinkronisasi atau operasi atom .


int main(){int i=i;}

4.1 Konversi nilai-ke-nilai [conv.lval]

1 - [...] Jika objek yang direferensikan oleh glvalue adalah [...] tidak diinisialisasi, sebuah program yang mengharuskan konversi ini memiliki perilaku yang tidak ditentukan.


//^L.

Berikut ^Lini adalah karakter umpan formulir, yang merupakan bagian dari rangkaian karakter dasar. 4 karakter (baris baru tidak diperlukan per 2.2: 2). Perilaku tidak terdefinisi adalah per

2.8 Komentar [lex.comment]

1 - Jika ada umpan formulir atau karakter tab vertikal dalam //komentar [a- style], hanya karakter spasi putih yang akan muncul di antara itu dan baris baru yang mengakhiri komentar; tidak diperlukan diagnostik.


yang kedua tidak jelas. Itu dapat mengoptimalkan loop for tanpa masalah. Itu bukan perilaku yang tidak jelas.
rubenvb

3
@rubenvb stackoverflow.com/questions/3592557/... - kapan saja standar mengatakan "kompiler dapat mengasumsikan P," tersirat bahwa sebuah program yang memiliki properti bukan-P memiliki semantik yang tidak ditentukan .
ecatmur

namun kompiler juga dapat menganggap tidak ada efek samping ketika memilih copy constructor.
rubenvb

@rubenvb karena kasus khusus itu disebutkan secara eksplisit .
R. Martinho Fernandes

1
@BogdanAlexandru proyek sematan Anda memiliki perilaku yang tidak terdefinisi. Itu berarti bahwa itu mungkin berfungsi seperti yang Anda harapkan sekarang, tetapi ketika Anda meningkatkan kompiler Anda akan berperilaku berbeda.
ecatmur

5
\u\
0000

Ini memiliki delapan karakter, dan memiliki perilaku yang tidak terdefinisi, menurut §2.2 / 1.

Setiap instance karakter backslash ( \) segera diikuti oleh karakter baris baru dihapus, menyambungkan baris sumber fisik untuk membentuk garis sumber logis. Hanya backslash terakhir pada baris sumber fisik mana saja yang memenuhi syarat untuk menjadi bagian dari sambungan tersebut. Jika, sebagai akibatnya, urutan karakter yang cocok dengan sintaks nama karakter-universal diproduksi, perilaku tidak terdefinisi.


ini bukan & "program". Suatu program memiliki main.
rubenvb

@rubenvb Cobalah di Hell ++. Ini memiliki perilaku yang tidak terdefinisi, sehingga dapat menjadi program tanpa main. Sulit untuk menegakkan aturan ketika Anda meminta sebuah program yang tidak memiliki aturan untuk diikuti (itulah yang dimaksud UB!).
R. Martinho Fernandes

3
Berdasarkan kata-kata dari pertanyaan, saya pikir ini memenuhi syarat - hanya meminta "kode" terpendek yang menampilkan UB. Berdasarkan "runnable" dalam komentar, saya pikir maksudnya, bagaimanapun, adalah program terpendek , yang akan mengesampingkan kode Anda, karena menurut §3.6.1 / 1: "Suatu program harus berisi fungsi global yang disebut main, yang merupakan awal dari program yang ditunjuk. " Dengan demikian, tanpa main, apa yang Anda miliki adalah bentukan.
Jerry Coffin

1
@JerryCoffin Dia menggunakan lingkungan berdiri bebas di mana main tidak diperlukan. Anda dengan mudah meninggalkan sisa §3.6.1 / 1 yang mengatakan "Ini adalah implementasi-ditentukan apakah suatu program dalam lingkungan berdiri bebas diperlukan untuk mendefinisikan fungsi utama.". Ini adalah program yang valid ("valid" seperti di dalamnya "program" menurut argumen Anda).
David

Dang, baru saja datang ke sini untuk membawa yang itu. +1
Columbo

2
#include. /*Imagine a new-line right after the dot*/

§16.2 / 4:

Arahan preprocessing dari formulir

             #include  pp-token baris baru

(yang tidak cocok dengan salah satu dari dua formulir sebelumnya) diizinkan. [..] Jika arahan yang dihasilkan setelah semua penggantian tidak cocok dengan salah satu dari dua formulir sebelumnya, perilaku tidak terdefinisi.


Tidakkah akan menguraikan sama jika Anda menghapus ruang sebelum titik?
feersum

@feersum Yap. Itu tidak mengubah ide, itulah sebabnya saya menghindarinya untuk meningkatkan keterbacaan, tapi saya kira itu melayani titik pertanyaan untuk menggambarkan bahwa ruang dapat dihilangkan. Terima kasih!
Columbo

2
int main(){int i=1>>-1;}

Penjelasan:

C ++ 98 dan C ++ 11 §5.8 / 1 keduanya menyatakan itu

Perilaku tidak terdefinisi jika operan kanan negatif, atau lebih besar dari atau sama dengan panjang dalam bit dari operan kiri yang dipromosikan.


3
pada sistem 32-bit, bukankah panjang dalam bit intbiasanya 32? mengubah RHS dari pergeseran ke -1adalah jumlah karakter yang sama dan tidak akan bergantung pada ukuran bilangan bulat
ardnew

1

Jika seseorang mempercayai wikipedia, berikut adalah beberapa:

Mengubah string dikatakan menyebabkan perilaku yang tidak terdefinisi. Itu selalu berhasil untuk saya.

int main(int c,char*v){v[0]='.';}

Fungsi yang tidak batal tanpa pengembalian menyebabkan nilai pengembalian yang tidak ditentukan.

int a(){}
int main(){return a();}

Pembagian (int?) Dengan nol seharusnya tidak ditentukan. Yang saya tahu adalah crash.

int main(int c){c/0;}

Ini bukan cuplikan kode hukum. Utama harus didefinisikan sebagai int main(){}paling tidak.
rubenvb

Sial, saya yakin pertanyaannya adalah tentang C. Maaf tentang itu.
shiona

1
@shiona parameter kedua seharusnya char **tidak char *. Anda hanya memodifikasi bagian dari nilai pointer. Bahkan, argvdijamin aman dimodifikasi.
oldrinb

Standar ini memungkinkan string literal hanya-baca, sehingga banyak implementasi yang melakukannya. Itu benar untuk char *argv[]tidak memiliki constkualifikasi. Anda dapat menabrak dengan menulis ke string literal denganint main(){char *v="";*v=1;}
Peter Cordes

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.