Saya tahu variabel lokal yang tidak diinisialisasi adalah perilaku tidak terdefinisi ( UB ), dan juga nilainya mungkin memiliki representasi jebakan yang dapat mempengaruhi operasi lebih lanjut, tetapi kadang-kadang saya ingin menggunakan nomor acak hanya untuk representasi visual dan tidak akan menggunakannya lebih lanjut di bagian lain dari program, misalnya, mengatur sesuatu dengan warna acak dalam efek visual, misalnya:
void updateEffect(){
for(int i=0;i<1000;i++){
int r;
int g;
int b;
star[i].setColor(r%255,g%255,b%255);
bool isVisible;
star[i].setVisible(isVisible);
}
}
apakah itu lebih cepat dari
void updateEffect(){
for(int i=0;i<1000;i++){
star[i].setColor(rand()%255,rand()%255,rand()%255);
star[i].setVisible(rand()%2==0?true:false);
}
}
dan juga lebih cepat dari generator nomor acak lainnya?
c++
c
undefined-behavior
garbage
ggrr
sumber
sumber
Jawaban:
Seperti yang telah dicatat oleh orang lain, ini adalah Perilaku Tidak Terdefinisi (UB).
Dalam praktiknya, itu akan (mungkin) benar-benar (jenis) bekerja. Membaca dari register yang tidak diinisialisasi pada arsitektur x86 [-64] memang akan menghasilkan hasil sampah, dan mungkin tidak akan melakukan hal buruk (sebagai lawan dari mis Itanium, di mana register dapat ditandai sebagai tidak valid , sehingga membaca kesalahan propagasi seperti NaN).
Ada dua masalah utama:
Ini tidak akan terlalu acak. Dalam hal ini, Anda membaca dari tumpukan, sehingga Anda akan mendapatkan apa pun yang ada di sana sebelumnya. Yang mungkin acak, terstruktur sepenuhnya, kata sandi yang Anda masukkan sepuluh menit yang lalu, atau resep kue nenek Anda.
Adalah praktik buruk (huruf kapital 'B') untuk membiarkan hal-hal seperti ini merayapi kode Anda. Secara teknis, kompiler dapat memasukkan
reformat_hdd();
setiap kali Anda membaca variabel yang tidak ditentukan. Tidak akan , tetapi Anda tidak harus tetap melakukannya. Jangan lakukan hal-hal yang tidak aman. Semakin sedikit pengecualian yang Anda buat, semakin aman Anda dari kesalahan yang tidak disengaja sepanjang waktu.Masalah yang lebih mendesak dengan UB adalah bahwa hal itu membuat perilaku seluruh program Anda tidak terdefinisi. Kompiler modern dapat menggunakan ini untuk menghilangkan sebagian besar kode Anda atau bahkan kembali ke masa lalu . Bermain dengan UB seperti insinyur Victoria yang membongkar reaktor nuklir langsung. Ada banyak hal yang salah, dan Anda mungkin tidak akan tahu setengah dari prinsip dasar atau teknologi yang diimplementasikan. Ini mungkin baik-baik saja, tapi Anda masih tidak boleh membiarkan hal itu terjadi. Lihatlah jawaban bagus lainnya untuk perincian.
Juga, saya akan memecat Anda.
sumber
unreachable()
dan menghapus setengah dari program Anda. Ini juga terjadi dalam praktik. Perilaku ini benar-benar menetralkan RNG di beberapa distro Linux yang saya percaya .; Sebagian besar jawaban dalam pertanyaan ini tampaknya menganggap bahwa nilai yang tidak diinisialisasi berlaku seperti nilai sama sekali. Itu salah.Izinkan saya mengatakan ini dengan jelas: kami tidak meminta perilaku yang tidak ditentukan dalam program kami . Itu tidak pernah merupakan ide yang bagus, titik. Ada pengecualian langka untuk aturan ini; misalnya, jika Anda adalah pelaksana perpustakaan yang menerapkan offsetof . Jika kasing Anda berada dalam pengecualian seperti itu, Anda mungkin sudah tahu ini. Dalam hal ini kita tahu menggunakan variabel otomatis tidak diinisialisasi adalah perilaku yang tidak terdefinisi .
Kompiler menjadi sangat agresif dengan optimisasi di sekitar perilaku yang tidak terdefinisi dan kami dapat menemukan banyak kasus di mana perilaku yang tidak terdefinisi telah menyebabkan kelemahan keamanan. Kasus yang paling terkenal mungkin adalah penghapusan cek pointer nol kernel Linux yang saya sebutkan dalam jawaban saya untuk bug kompilasi C ++? di mana optimisasi kompiler di sekitar perilaku yang tidak ditentukan mengubah perulangan menjadi yang tak terbatas.
Kita dapat membaca Optimalisasi CERT yang Berbahaya dan Kehilangan Kausalitas ( video ) yang mengatakan, antara lain:
Khususnya berkenaan dengan nilai-nilai tak tentu, laporan cacat standar C 451: Ketidakstabilan variabel otomatis tidak diinisialisasi membuat beberapa bacaan yang menarik. Ini belum diselesaikan tetapi memperkenalkan konsep nilai goyah yang berarti ketidakpastian suatu nilai dapat menyebar melalui program dan dapat memiliki nilai tak tentu yang berbeda di berbagai titik dalam program.
Saya tidak tahu ada contoh di mana ini terjadi tetapi pada titik ini kita tidak bisa mengesampingkannya.
Contoh nyata, bukan hasil yang Anda harapkan
Anda tidak mungkin mendapatkan nilai acak. Sebuah kompiler dapat mengoptimalkan loop jauh sama sekali. Misalnya, dengan case sederhana ini:
dentang mengoptimalkannya ( lihat langsung ):
atau mungkin dapatkan semua nol, seperti halnya case yang dimodifikasi ini:
lihat langsung :
Kedua kasus ini adalah bentuk perilaku yang tidak dapat diterima secara sempurna.
Catatan, jika kita menggunakan Itanium kita bisa berakhir dengan nilai jebakan :
Catatan penting lainnya
Sangat menarik untuk mencatat perbedaan antara gcc dan dentang yang dicatat dalam proyek Canaries UB tentang seberapa bersedia mereka untuk mengambil keuntungan dari perilaku yang tidak terdefinisi sehubungan dengan memori yang tidak diinisialisasi. Catatan artikel ( penekanan saya ):
Seperti yang ditunjukkan oleh Matthieu M., Apa yang Harus Diketahui Setiap Pemrogram C Tentang Perilaku Tidak Terdefinisi # 2/3 juga relevan dengan pertanyaan ini. Itu mengatakan antara lain ( penekanan milikku ):
Demi kelengkapan saya mungkin harus menyebutkan bahwa implementasi dapat memilih untuk membuat perilaku yang tidak terdefinisi dengan baik, misalnya gcc memungkinkan jenis hukuman melalui serikat pekerja sementara di C ++ ini tampak seperti perilaku yang tidak terdefinisi . Jika ini masalahnya, implementasi harus mendokumentasikannya dan ini biasanya tidak portabel.
sumber
Tidak, ini mengerikan.
Perilaku menggunakan variabel yang tidak diinisialisasi tidak ditentukan dalam C dan C ++, dan sangat tidak mungkin bahwa skema seperti itu akan memiliki sifat statistik yang diinginkan.
Jika Anda menginginkan generator nomor acak "cepat dan kotor", maka
rand()
itulah taruhan terbaik Anda. Dalam implementasinya, yang dilakukannya hanyalah multiplikasi, tambahan, dan modulus.Generator tercepat yang saya tahu mengharuskan Anda untuk menggunakan
uint32_t
sebagai jenis variabel pseudo-acakI
, dan menggunakanI = 1664525 * I + 1013904223
untuk menghasilkan nilai-nilai berturut-turut. Anda dapat memilih nilai awal apa pun
I
(disebut benih ) yang disukai Anda. Jelas Anda dapat membuat kode sebaris itu. Sampul yang dijamin standar dari tipe yang tidak ditandatangani bertindak sebagai modulus. (Konstanta numerik dipilih langsung oleh programmer ilmiah yang luar biasa itu, Donald Knuth.)sumber
rand()
tidak cocok untuk tujuan dan harus sepenuhnya ditinggalkan, menurut pendapat saya. Saat ini Anda dapat mengunduh generator nomor acak yang berlisensi dan jauh lebih unggul (mis. Mersenne Twister) yang sangat cepat dengan kemudahan terbesar sehingga benar-benar tidak perlu terus menggunakan yang sangat cacatrand()
Pertanyaan bagus!
Tidak terdefinisi tidak berarti itu acak. Pikirkan tentang hal ini, nilai-nilai yang Anda dapatkan dalam variabel global yang tidak diinisialisasi ditinggalkan di sana oleh sistem atau aplikasi Anda / lainnya yang sedang berjalan. Bergantung apa yang sistem Anda lakukan dengan memori yang tidak lagi digunakan dan / atau nilai-nilai apa yang dihasilkan sistem dan aplikasi, Anda mungkin mendapatkan:
Nilai yang akan Anda dapatkan sepenuhnya bergantung pada nilai non-acak yang ditinggalkan oleh sistem dan / atau aplikasi. Jadi, memang akan ada beberapa kebisingan (kecuali sistem Anda menghapus memori yang tidak digunakan lagi), tetapi kumpulan nilai dari mana Anda akan menggambar tidak akan acak.
Hal-hal menjadi jauh lebih buruk untuk variabel lokal karena ini datang langsung dari tumpukan program Anda sendiri. Ada peluang yang sangat baik bahwa program Anda akan benar-benar menulis lokasi tumpukan ini selama eksekusi kode lainnya. Saya memperkirakan peluang keberuntungan dalam situasi ini sangat rendah, dan perubahan kode 'acak' yang Anda buat mencoba keberuntungan ini.
Baca tentang keacakan . Seperti yang akan Anda lihat, keacakan adalah properti yang sangat spesifik dan sulit diperoleh. Adalah kesalahan umum untuk berpikir bahwa jika Anda hanya mengambil sesuatu yang sulit dilacak (seperti saran Anda) Anda akan mendapatkan nilai acak.
sumber
Banyak jawaban bagus, tetapi izinkan saya untuk menambahkan yang lain dan tekankan bahwa di komputer deterministik, tidak ada yang acak. Ini berlaku untuk angka yang dihasilkan oleh pseudo-RNG dan angka yang "acak" yang ditemukan di area memori yang disediakan untuk variabel lokal C / C ++ pada stack.
TAPI ... ada perbedaan penting.
Angka-angka yang dihasilkan oleh generator pseudorandom yang baik memiliki properti yang membuatnya secara statistik mirip dengan undian yang benar-benar acak. Misalnya, distribusinya seragam. Panjang siklus panjang: Anda bisa mendapatkan jutaan angka acak sebelum siklus berulang. Urutannya tidak berkorelasi otomatis: misalnya, Anda tidak akan mulai melihat pola aneh muncul jika Anda mengambil setiap angka ke-2, ke-3, atau ke-27, atau jika Anda melihat angka-angka tertentu dalam angka yang dihasilkan.
Sebaliknya, angka "acak" yang tertinggal di tumpukan tidak memiliki properti ini. Nilai-nilai mereka dan keacakan nyata mereka bergantung sepenuhnya pada bagaimana program itu dibangun, bagaimana itu dikompilasi, dan bagaimana itu dioptimalkan oleh kompiler. Sebagai contoh, berikut adalah variasi ide Anda sebagai program mandiri:
Ketika saya mengkompilasi kode ini dengan GCC pada mesin Linux dan menjalankannya, ternyata menjadi deterministik yang agak tidak menyenangkan:
Jika Anda melihat kode yang dikompilasi dengan disassembler, Anda dapat merekonstruksi apa yang sedang terjadi, secara detail. Panggilan pertama ke notrandom () menggunakan area stack yang sebelumnya tidak digunakan oleh program ini; siapa tahu apa yang ada di sana. Tapi setelah panggilan itu ke notrandom (), ada panggilan ke printf () (yang sebenarnya dioptimalkan oleh kompiler GCC untuk panggilan ke putchar (), tapi tidak apa-apa) dan yang menimpa tumpukan. Jadi waktu berikutnya dan berikutnya, ketika notrandom () dipanggil, stack akan berisi data basi dari eksekusi putchar (), dan karena putchar () selalu dipanggil dengan argumen yang sama, data basi ini akan selalu sama, terlalu.
Jadi sama sekali tidak ada yang acak tentang perilaku ini, juga angka-angka yang diperoleh dengan cara ini tidak memiliki sifat yang diinginkan dari generator nomor pseudorandom yang ditulis dengan baik. Bahkan, dalam sebagian besar skenario kehidupan nyata, nilai-nilai mereka akan berulang dan sangat berkorelasi.
Memang, seperti yang lain, saya juga akan secara serius mempertimbangkan memecat seseorang yang mencoba untuk menularkan ide ini sebagai "RNG kinerja tinggi".
sumber
/dev/random
sering diunggulkan dari sumber perangkat keras seperti itu, dan pada kenyataannya "noise kuantum", yaitu benar-benar tidak dapat diprediksi dalam arti fisik terbaik dari kata tersebut.Perilaku tidak terdefinisi berarti bahwa pembuat kompiler bebas untuk mengabaikan masalah karena programmer tidak akan pernah memiliki hak untuk mengeluh apa pun yang terjadi.
Sementara secara teori ketika memasuki tanah UB apa pun bisa terjadi (termasuk daemon yang terbang keluar dari hidung Anda ) yang biasanya berarti bahwa penulis kompiler tidak akan peduli dan, untuk variabel lokal, nilainya akan menjadi apa pun yang ada di memori tumpukan pada saat itu .
Ini juga berarti bahwa seringkali isinya akan "aneh" tetapi tetap atau sedikit acak atau variabel tetapi dengan pola yang jelas (misalnya meningkatkan nilai pada setiap iterasi).
Pasti Anda tidak bisa berharap itu menjadi generator acak yang layak.
sumber
Perilaku tidak terdefinisi tidak terdefinisi. Itu tidak berarti bahwa Anda mendapatkan nilai yang tidak ditentukan, itu berarti bahwa program dapat melakukan apa saja dan masih memenuhi spesifikasi bahasa.
Compiler pengoptimalan yang baik harus diambil
dan kompilasi ke noop. Ini tentu saja lebih cepat daripada alternatif apa pun. Ini memiliki kelemahan yang tidak akan melakukan apa-apa, tetapi itu adalah kelemahan dari perilaku yang tidak terdefinisi.
sumber
-Wall -Wextra
.Belum disebutkan, tetapi jalur kode yang menjalankan perilaku tidak terdefinisi diizinkan untuk melakukan apa pun yang diinginkan kompilator, mis
Yang pasti lebih cepat dari loop yang benar, dan karena UB, sangat sesuai.
sumber
Karena alasan keamanan, memori baru yang ditetapkan untuk suatu program harus dibersihkan, jika tidak informasi tersebut dapat digunakan, dan kata sandi dapat bocor dari satu aplikasi ke aplikasi lainnya. Hanya ketika Anda menggunakan kembali memori, Anda mendapatkan nilai yang berbeda dari 0. Dan sangat mungkin, bahwa pada stack nilai sebelumnya baru saja diperbaiki, karena penggunaan memori sebelumnya sudah diperbaiki.
sumber
Contoh kode khusus Anda mungkin tidak akan melakukan apa yang Anda harapkan. Sementara secara teknis setiap iterasi dari loop menciptakan kembali variabel lokal untuk nilai r, g, dan b, dalam praktiknya itu adalah ruang memori yang sama persis pada stack. Oleh karena itu ia tidak akan diacak ulang dengan setiap iterasi, dan Anda akhirnya akan menetapkan 3 nilai yang sama untuk masing-masing 1000 warna, terlepas dari seberapa acak r, g, dan b secara individual dan awalnya.
Memang, jika itu berhasil, saya akan sangat ingin tahu apa yang mengacak ulang itu. Satu-satunya hal yang dapat saya pikirkan adalah interleave interrupt yang dibajak di atas tumpukan itu, sangat tidak mungkin. Mungkin optimasi internal yang menjadikannya sebagai variabel register daripada sebagai lokasi memori yang sebenarnya, di mana register digunakan kembali lebih jauh dalam loop, akan melakukan trik, juga, terutama jika fungsi visibilitas yang diatur terutama register-hung. Namun, masih jauh dari acak.
sumber
Karena sebagian besar orang di sini menyebutkan perilaku yang tidak terdefinisi. Tidak terdefinisi juga berarti bahwa Anda mungkin mendapatkan beberapa nilai integer yang valid (untungnya) dan dalam hal ini akan lebih cepat (karena panggilan fungsi rand tidak dilakukan). Tapi jangan praktis menggunakannya. Saya yakin ini akan hasil yang mengerikan karena keberuntungan tidak bersama Anda sepanjang waktu.
sumber
Sangat buruk! Kebiasaan buruk, hasil buruk. Mempertimbangkan:
Jika fungsinya
A_Function_that_use_a_lot_the_Stack()
membuat inisialisasi yang selalu sama, ia meninggalkan tumpukan dengan data yang sama. Data itulah yang kami panggilupdateEffect()
: selalu bernilai sama! .sumber
Saya melakukan tes yang sangat sederhana, dan itu tidak acak sama sekali.
Setiap kali saya menjalankan program, ia mencetak nomor yang sama (
32767
dalam kasus saya) - Anda tidak bisa mendapatkan jauh lebih sedikit dari itu. Ini mungkin apa pun kode startup di pustaka runtime yang tersisa di stack. Karena ia menggunakan kode startup yang sama setiap kali program berjalan, dan tidak ada yang berbeda dalam program antar kali, hasilnya sangat konsisten.sumber
Anda harus memiliki definisi tentang apa yang Anda maksud dengan 'acak'. Definisi yang masuk akal melibatkan bahwa nilai-nilai yang Anda dapatkan harus memiliki sedikit korelasi. Itu sesuatu yang bisa Anda ukur. Ini juga tidak mudah untuk dicapai dengan cara yang terkontrol dan dapat direproduksi. Jadi perilaku yang tidak terdefinisi tentu bukan yang Anda cari.
sumber
Ada situasi tertentu di mana memori yang tidak diinisialisasi dapat dibaca dengan aman menggunakan tipe "unsigned char *" [misalnya buffer yang dikembalikan dari
malloc
]. Kode dapat membaca memori seperti itu tanpa harus khawatir tentang kompiler yang membuang kausalitas ke luar jendela, dan ada kalanya mungkin lebih efisien untuk menyiapkan kode untuk apa pun yang mungkin dikandung memori daripada memastikan bahwa data yang tidak diinisialisasi tidak akan dibaca ( contoh umum dari ini akan digunakanmemcpy
pada buffer yang diinisialisasi sebagian daripada menyalin semua elemen yang berisi data yang bermakna).Bahkan dalam kasus seperti itu, bagaimanapun, kita harus selalu berasumsi bahwa jika kombinasi byte akan sangat menjengkelkan, membacanya akan selalu menghasilkan pola byte (dan jika pola tertentu akan menjadi vexatious dalam produksi, tetapi tidak dalam pengembangan, seperti pola tidak akan muncul sampai kode diproduksi).
Membaca memori yang tidak diinisialisasi mungkin berguna sebagai bagian dari strategi generasi acak dalam sistem tertanam di mana orang dapat yakin memori tidak pernah ditulis dengan konten yang secara substansial non-acak sejak terakhir kali sistem dinyalakan, dan jika manufaktur proses yang digunakan untuk memori menyebabkan status power-on bervariasi secara semi-acak. Kode harus berfungsi bahkan jika semua perangkat selalu menghasilkan data yang sama, tetapi dalam kasus di mana misalnya sekelompok node masing-masing harus memilih ID unik sembarang mungkin, memiliki generator "tidak terlalu acak" yang memberikan setengah node awal yang sama ID mungkin lebih baik daripada tidak memiliki sumber asal keacakan sama sekali.
sumber
Seperti yang orang lain katakan, itu akan cepat, tetapi tidak acak.
Apa yang kebanyakan kompiler akan lakukan untuk variabel lokal adalah untuk mengambil beberapa ruang untuk mereka di stack, tetapi tidak repot mengaturnya untuk apa pun (standar mengatakan mereka tidak perlu, jadi mengapa memperlambat kode yang Anda hasilkan?).
Dalam hal ini, nilai yang Anda dapatkan akan tergantung pada apa yang sebelumnya ada di stack - jika Anda memanggil fungsi sebelum ini yang memiliki seratus variabel char lokal semua diatur ke 'Q' dan kemudian memanggil fungsi Anda setelah yang kembali, maka Anda mungkin akan menemukan nilai-nilai "acak" Anda berperilaku seolah-olah Anda memiliki
memset()
semuanya untuk 'Q's.Yang penting untuk fungsi contoh Anda mencoba menggunakan ini, nilai-nilai ini tidak akan berubah setiap kali Anda membacanya, mereka akan sama setiap kali. Jadi Anda akan mendapatkan 100 bintang yang diatur dengan warna dan visibilitas yang sama.
Juga, tidak ada yang mengatakan bahwa kompiler tidak boleh menginisialisasi nilai ini - jadi kompiler masa depan mungkin melakukannya.
Secara umum: ide buruk, jangan lakukan itu. (seperti banyak optimasi tingkat kode "pintar" benar-benar ...)
sumber
Seperti yang telah disebutkan orang lain, ini adalah perilaku tidak terdefinisi ( UB ), tetapi mungkin "berhasil".
Kecuali dari masalah yang telah disebutkan oleh orang lain, saya melihat satu masalah lain (kerugian) - itu tidak akan berfungsi dalam bahasa apa pun selain C dan C ++. Saya tahu bahwa pertanyaan ini adalah tentang C ++, tetapi jika Anda dapat menulis kode yang akan menjadi C ++ dan kode Java yang baik dan itu bukan masalah maka mengapa tidak? Mungkin suatu hari seseorang harus mem-port-nya ke bahasa lain dan mencari bug yang disebabkan oleh
"trik sulap"UB seperti ini pasti akan menjadi mimpi buruk (terutama untuk pengembang C / C ++ yang tidak berpengalaman).Di sini ada pertanyaan tentang UB serupa lainnya. Bayangkan saja Anda mencoba menemukan bug seperti ini tanpa mengetahui tentang UB ini. Jika Anda ingin membaca lebih lanjut tentang hal-hal aneh di C / C ++, baca jawaban untuk pertanyaan dari tautan dan lihat slideshow BESAR ini . Ini akan membantu Anda memahami apa yang ada di balik tudung dan bagaimana cara kerjanya; ini bukan hanya tampilan slide lain yang penuh dengan "sihir". Saya cukup yakin bahwa sebagian besar programmer C / c ++ yang berpengalaman dapat belajar banyak dari ini.
sumber
Bukan ide yang baik untuk mengandalkan logika apa pun pada perilaku bahasa yang tidak terdefinisi. Selain apa pun yang disebutkan / dibahas dalam posting ini, saya ingin menyebutkan bahwa dengan pendekatan C ++ modern / gaya program seperti itu mungkin tidak dapat dikompilasi.
Ini disebutkan dalam posting saya sebelumnya yang berisi keunggulan fitur otomatis dan tautan bermanfaat untuk hal yang sama.
https://stackoverflow.com/a/26170069/2724703
Jadi, jika kita mengubah kode di atas dan mengganti tipe aktual dengan otomatis , program bahkan tidak dapat dikompilasi.
sumber
Saya suka cara berpikir Anda. Benar-benar di luar kotak. Namun tradeoff benar-benar tidak sepadan. Memory-runtime tradeoff adalah sesuatu, termasuk perilaku tidak terdefinisi untuk runtime tidak .
Itu harus memberi Anda perasaan yang sangat meresahkan untuk mengetahui Anda menggunakan "acak" seperti logika bisnis Anda. Saya tidak akan melakukannya.
sumber
Gunakan
7757
setiap tempat Anda tergoda untuk menggunakan variabel yang tidak diinisialisasi. Saya mengambilnya secara acak dari daftar bilangan prima:itu didefinisikan perilaku
dijamin tidak selalu 0
itu prima
itu mungkin secara statistik acak sebagai variabel tidak terinualisasi
itu cenderung lebih cepat daripada variabel tidak diinisialisasi karena nilainya diketahui pada waktu kompilasi
sumber
Ada satu lagi kemungkinan untuk dipertimbangkan.
Kompiler modern (ahem g ++) sangat cerdas sehingga mereka menelusuri kode Anda untuk melihat instruksi apa yang mempengaruhi status, dan apa yang tidak, dan jika sebuah instruksi dijamin TIDAK mempengaruhi status, g ++ hanya akan menghapus instruksi itu.
Jadi, inilah yang akan terjadi. g ++ pasti akan melihat bahwa Anda membaca, menjalankan aritmatika, menyimpan, apa yang pada dasarnya merupakan nilai sampah, yang menghasilkan lebih banyak sampah. Karena tidak ada jaminan bahwa sampah baru lebih berguna daripada yang lama, itu hanya akan menghilangkan loop Anda. BLOOP!
Metode ini berguna, tetapi inilah yang akan saya lakukan. Gabungkan UB (Undefined Behavior) dengan rand () speed.
Tentu saja, kurangi
rand()
s dieksekusi, tetapi campur mereka jadi compiler tidak melakukan apa pun yang tidak Anda inginkan.Dan aku tidak akan memecatmu.
sumber
Menggunakan data yang tidak diinisialisasi untuk keacakan tidak selalu merupakan hal yang buruk jika dilakukan dengan benar. Faktanya, OpenSSL melakukan hal ini untuk menaburkan PRNG-nya.
Tampaknya penggunaan ini tidak didokumentasikan dengan baik, karena seseorang memperhatikan Valgrind mengeluh tentang penggunaan data yang tidak diinisialisasi dan "memperbaikinya", menyebabkan bug pada PRNG .
Jadi Anda bisa melakukannya, tetapi Anda perlu tahu apa yang Anda lakukan dan memastikan bahwa siapa pun yang membaca kode Anda memahami hal ini.
sumber