Apakah ada dokumentasi khusus untuk perilaku i=i-- di gcc?

Sekali lagi, masalah seperti "i=i--" yang paling kami sukai. Di C99 kami memiliki:

6.5 Ekspresi #2: Antara titik urutan sebelumnya dan berikutnya suatu objek harus memiliki nilai tersimpan yang diubah paling banyak satu kali

70) Paragraf ini menjadi !!tidak terdefinisi!! ekspresi pernyataan seperti

i = ++i + 1;

Namun untuk perilaku yang tidak dapat ditentukan, terdapat varian dari keluaran acak hingga "eksekusi program secara terdokumentasi" (c99 3.4.3)

Jadi, pertanyaannya:

Apakah gcc mendokumentasikan perilaku untuk pernyataan i=i++, i=i--, dan seterusnya?

Kode sebenarnya adalah

int main(){int i=2;i=i--;return i;}

person osgx    schedule 25.08.2010    source sumber
comment
Tidak, gcc tidak mendokumentasikan fungsinya dalam kasus ini. Implementor Gcc, antara lain, mencari kecepatan kode yang dihasilkan. Mendokumentasikan apa yang dilakukan contoh ini akan bertentangan dengan tujuan ini. Membuat programmer yang menulis kode seperti contoh ini bahagia tidak ada bobotnya dibandingkan dengan meningkatkan hasil benchmark.   -  person Pascal Cuoq    schedule 25.08.2010


Jawaban (4)


GCC tidak mendokumentasikan perilaku ini. Laman Opsi Peringatan menyebutkan masalah titik urutan di -Wsequence-point, namun tidak memberi petunjuk pada semantik yang terdefinisi dengan baik untuk pelanggaran.

GCC memang memiliki daftar C yang bagus Perilaku yang Ditetapkan Implementasi, tetapi saya juga tidak dapat menemukan referensi apa pun mengenai masalah ini di sini.

person schot    schedule 25.08.2010
comment
Saya tidak yakin bagaimana keadaannya sekarang, tapi di masa lalu, orang-orang GCC bila memungkinkan secara terbuka pro-standar. TKI, kalau standar bilang tidak terdefinisi atau unspecified maka di GCC. - person Dummy00001; 25.08.2010

Terserah pada implementasi back-end untuk memutuskan apa fungsinya. Anda dapat menggunakan -S dan memeriksa kode yang dihasilkan untuk menentukan urutan kejadian yang tepat.

person Ignacio Vazquez-Abrams    schedule 25.08.2010
comment
Apakah ada dokumen mengenai kasus seperti itu? - person osgx; 25.08.2010
comment
dan apa backend di GCC? Apakah akan berbeda untuk x86 dan sparc misalnya? - person osgx; 25.08.2010
comment
Perilaku yang tidak terdefinisi berarti bahwa segala sesuatu adalah permainan yang adil. Kompiler dapat memilih untuk menghasilkan kode yang berbeda pada hari yang berbeda dalam seminggu. - person jamesdlin; 25.08.2010
comment
@jamesdlin, Ya, kompiler mungkin memulai permainan Hanoi di Emacs pada hari ke-13 setiap bulannya, tetapi biasanya tidak. Dan untuk versi dan platform kompiler tetap, hasilnya sama bahkan untuk level -O yang berbeda - person osgx; 27.08.2010

Itu tidak didokumentasikan tetapi meskipun demikian, saya tidak ingin membacanya. Anda tidak boleh bergantung pada apa yang dilakukan implementasi tertentu ketika mengalami perilaku tidak terdefinisi.

person mtvec    schedule 25.08.2010
comment
Jika didokumentasikan, saya dapat mengandalkan, bahwa GCC dengan beberapa versi akan melakukan itu, apa yang telah didokumentasikan. Ya, kode saya akan salah untuk kompiler lain, tetapi tidak untuk GCC - person osgx; 25.08.2010
comment
@osgx: Mungkin Anda bisa, tetapi menurut saya ini akan menimbulkan lebih banyak masalah daripada manfaatnya. Misalnya, ini sangat membingungkan orang yang membaca kode Anda. Dan mengapa Anda ingin melakukan sesuatu seperti i = i--? Anda harus tahu apa yang Anda ingin lakukan, jadi mengapa tidak mengejanya dalam C++ yang benar? - person mtvec; 25.08.2010
comment
kasus ini datang kepada kami dari set pengujian besar kami, sebagian ditulis oleh penguji kami. Mereka memiliki tingkat kemampuan bahasa C yang ''sangat'' berbeda. - person osgx; 25.08.2010
comment
@osgx: menakutkan. Saya akan memaksa mereka untuk selalu mengkompilasi dengan -Wall, yang merupakan ide bagus. Ini khususnya akan mengaktifkan -Wsequence-point yang disebutkan oleh scshot. - person Jens Gustedt; 25.08.2010
comment
@osgx Sekarang setelah saya memahami konteksnya sedikit lebih baik, saya rasa saya dapat menyebutkan penganalisis statis yang saya dan orang lain kerjakan (lihat bio saya). Ia menemukan banyak perilaku yang tidak terdefinisi atau tidak ditentukan jika kode yang dianalisis termasuk dalam subset C yang tepat. Sebaliknya, apakah ada tempat yang memiliki informasi lebih lanjut tentang pekerjaan di mana pertanyaan ini muncul di benak Anda? - person Pascal Cuoq; 25.08.2010
comment
@Pascal Cuoq, paket tes ini bersifat pribadi dan berada di bawah nda. Gcc mendeteksi i=i-- cukup baik, dan saya sering menggunakan opsi -W -Wall -Wextra -pedantic -ansi untuk gcc. Juga.. tampaknya pengujian asli memiliki ketergantungan data pada hasil i=i-- ini, tetapi, pada saat yang sama, akan berhasil dalam kedua pemahaman sepele tentang konstruksi ini. - person osgx; 25.08.2010

kenapa kamu ingin melakukan itu? Dengan serius. Saya penasaran.

person Dave Dopson    schedule 25.08.2010
comment
Kode ini ditemukan di set pengujian kompiler. Kumpulan pengujian ini berfungsi dengan baik untuk beberapa versi gcc. - person osgx; 25.08.2010
comment
Ini adalah perilaku yang tidak terdefinisi, jadi perilaku apa pun valid. Jika pengujian kompiler Anda menghasilkan tidak valid untuk kompiler mana pun, maka pengujian Anda rusak, karena pengujian tersebut harus selalu mengembalikan valid, terlepas dari apakah hasilnya 2, 3, 4 atau akhir alam semesta seperti yang kita kenal. Tentu saja, kita dapat memilih apakah perilaku yang tidak terdefinisi selalu valid atau selalu tidak valid. ;) - person Secure; 25.08.2010
comment
BTW, sudahkah Anda menguji apakah hasilnya konsisten di berbagai tingkat pengoptimalan? - person Secure; 25.08.2010
comment
@ Aman, Tes sebenarnya berhasil untuk kedua kasus i=i-- berfungsi. Ini akan melakukan jumlah iterasi yang berbeda, tetapi akan berhasil. Ini adalah ujian untuk kompiler, bukan untuk kepatuhan standar. Dalam versi gcc yang diuji, hasilnya sama untuk semua level -O yang diuji. - person osgx; 27.08.2010