Apa saja perilaku umum yang tidak terdefinisi yang harus diketahui oleh seorang programmer C ++?
Katakan, seperti:
a[i] = i++;
c++
undefined
undefined-behavior
c++-faq
yesraaj
sumber
sumber
Jawaban:
Pointer
NULL
pointermemcpy
untuk menyalin buffer yang tumpang tindih .Buffer meluap
Overflow Integer
int64_t i = 1; i <<= 72
ditentukan)Jenis, Pemain dan Konst
int i; i++; cout << i;
)volatile
atausig_atomic_t
pada saat menerima sinyalFungsi dan Templat
OOP
File sumber dan Preprocessing
long int
#if
ekspresiUntuk diklasifikasikan
sumber
Urutan yang parameter fungsi dievaluasi adalah perilaku yang tidak ditentukan . (Ini tidak akan membuat program Anda macet, meledak, atau memesan pizza ... tidak seperti perilaku yang tidak terdefinisi .)
Satu-satunya persyaratan adalah bahwa semua parameter harus dievaluasi sepenuhnya sebelum fungsi dipanggil.
Ini:
Dapat setara dengan ini:
Atau ini:
Ini bisa berupa; terserah kompiler. Hasilnya bisa berarti, tergantung pada efek sampingnya.
sumber
Kompiler bebas untuk memesan ulang bagian evaluasi ekspresi (dengan asumsi artinya tidak berubah).
Dari pertanyaan awal:
Penguncian ganda diperiksa. Dan satu kesalahan mudah dibuat.
sumber
Favorit saya adalah "rekursi tak terbatas dalam instantiasi templat" karena saya percaya itu satu-satunya di mana perilaku tidak terdefinisi terjadi pada waktu kompilasi.
sumber
Menetapkan ke konstan setelah pengupasan
const
menggunakanconst_cast<>
:sumber
Selain perilaku tidak terdefinisi , ada juga perilaku implementasi-didefinisikan sama jahatnya .
Perilaku tidak terdefinisi terjadi ketika suatu program melakukan sesuatu yang hasilnya tidak ditentukan oleh standar.
Perilaku yang didefinisikan oleh implementasi adalah tindakan oleh suatu program yang hasilnya tidak ditentukan oleh standar, tetapi implementasi tersebut diperlukan untuk didokumentasikan. Contohnya adalah "Multibyte karakter literal", dari pertanyaan Stack Overflow Apakah ada kompiler C yang gagal mengkompilasi ini? .
Perilaku yang ditentukan oleh implementasi hanya menggigit Anda ketika Anda memulai porting (tetapi memutakhirkan ke versi baru dari compiler juga porting!)
sumber
Variabel hanya dapat diperbarui sekali dalam ekspresi (secara teknis satu kali antara titik urutan).
sumber
Pemahaman dasar tentang berbagai batasan lingkungan. Daftar lengkapnya ada di bagian 5.2.4.1 dari spesifikasi C. Berikut beberapa di antaranya;
Saya sebenarnya sedikit terkejut dengan batas 1023 label kasus untuk pernyataan switch, saya bisa melihat bahwa terlampaui untuk kode yang dihasilkan / lex / parser cukup mudah.
Jika batas ini terlampaui, Anda memiliki perilaku yang tidak terdefinisi (crash, cacat keamanan, dll ...).
Benar, saya tahu ini dari spesifikasi C, tetapi C ++ membagikan dukungan dasar ini.
sumber
Menggunakan
memcpy
untuk menyalin antara wilayah memori yang tumpang tindih. Sebagai contoh:Perilaku tidak terdefinisi menurut Standar C, yang digolongkan oleh Standar C ++ 03.
7.21.2.1 Fungsi memcpy
7.21.2.2 Fungsi memmove
sumber
Satu-satunya tipe yang C ++ menjamin ukurannya
char
. Dan ukurannya adalah 1. Ukuran semua jenis lainnya tergantung platform.sumber
Objek level-Namespace di unit kompilasi yang berbeda tidak boleh bergantung satu sama lain untuk inisialisasi, karena urutan inisialisasi mereka tidak ditentukan.
sumber