Apakah ada manfaatnya untuk mendefinisikan variabel lokal konstan sebagai statis (c ++)?

10
void Animation::playAnimation() const
{
    static const int index = 0;
    const std::string& animationFileName = 
    m_animationContainer.getAnimationName(index);
    static const int zOrder = -1;
    static bool isLooping = false;

    AnimationBank::play(animationFileName,
                        zOrder,
                        isLooping);
}

Apakah ada manfaatnya untuk mendefinisikan variabel lokal konstan sebagai static? Atau itu tidak perlu dan bahkan praktik yang buruk.

TM
sumber
2
... juga, tolong jangan posting silang : stackoverflow.com/questions/44431574/... "Posting silang disukai karena mengarah ke jawaban yang terpecah-pecah tersebar di seluruh jaringan ..."
gnat

Jawaban:

10

Di luar @ Christophe jawaban yang sangat baik, kode yang dihasilkan untuk statis kemungkinan besar lebih buruk daripada yang untuk variabel lokal, jadi jika Anda tertarik dengan manfaat under-the-hood, statika lebih buruk pada prosesor modern.

Alasannya adalah bahwa statika harus ditempatkan di suatu tempat dalam memori yang dapat ditemukan oleh semua utas lainnya dan oleh semua doa lainnya. Ini pada dasarnya berarti menempatkan mereka dalam memori global.

Selama bertahun-tahun, prosesor & kompiler bersama-sama memiliki akses yang dioptimalkan secara signifikan ke variabel lokal karena popularitas penggunaannya, dibandingkan dengan variabel lain, seperti global, statika, dan bidang. Kompiler dapat memilih untuk menyimpan variabel lokal dalam register CPU, dan bahkan jika itu tidak (jadi ia menggunakan tumpukan doa), semua tumpukan hampir pasti ada dalam cache. Mengakses tumpukan biasanya merupakan mode pengalamatan perpindahan pendek (dari register penunjuk tumpukan). Namun, mengakses global atau statika biasanya memerlukan dan diperluas offset atau alamat absolut, sehingga instruksi yang dihasilkan lebih lama dari yang setara untuk akses memori stack.

Semua yang dikatakan, karena kombinasi statis dan const, kompiler dapat mendeteksi bahwa ia dapat menggantikan nilai konstan pada titik penggunaan, jadi mungkin penggunaan const mengurangi hal di atas. Tetap saja, cuplikan Anda menunjukkan setidaknya satu statika non-konstanta, jadi mungkin bahasannya topikal.

Erik Eidt
sumber
6
Apakah Anda yakin konstanta statis harus dimasukkan ke dalam memori?
MikeMB
5

Ini bukan pertanyaan tentang manfaat, tetapi pertanyaan tentang semantik:

  • Variabel statis dalam suatu fungsi (bahkan fungsi anggota), berarti bahwa variabel tersebut dibagi di antara semua panggilan fungsi tersebut. Jadi satu panggilan fungsi itu memiliki efek samping pada panggilan berikutnya.

  • Variabel non statis adalah unik untuk setiap eksekusi fungsi.

Jadi, kecuali diperlukan untuk alasan tertentu dan dibenarkan dengan baik, pertahankan variabel lokal tidak statis.

Komentar tambahan: Variabel statis juga dibagi di berbagai utas. Jadi memanggil fungsi ini dari lebih dari satu utas pada satu waktu dapat mengakibatkan kondisi balapan dan UB (bahkan jika dipanggil untuk objek yang berbeda).

Christophe
sumber
4
Mulai dari C ++ 11, standar mendefinisikan variabel statis thread safe. Non-const, variabel statis di sisi lain, tidak.
Teimpz
5
Ini tentang konstanta. Mereka tidak dapat mengubah nilainya, sehingga tidak ada perbedaan semantik yang berarti antara konstanta yang dibagi antara beberapa panggilan fungsi dan yang lokal.
MikeMB
Satu-satunya perbedaan adalah jika inisialisasi memiliki efek samping.
MikeMB
1
@MikeMB Memang, jawaban saya adalah umum. Jika itu adalah const, pengoptimal akan tetap menyebarkannya, apakah itu staticatau tidak. Tetapi masih ada perbedaan kecil: seperti yang Anda tunjukkan, penginisialisasi objek dapat menggunakan beberapa efek samping, sehingga memilih statis atau tidak dapat mengubah perilaku yang diharapkan. Untuk semua alasan ini, saya masih sangat menyarankan untuk menggunakan staticjika dan hanya jika constbenar-benar sesuatu yang secara intrinsik terkait dengan kelas. Tunjukkan maksud dalam kode dan biarkan pengoptimal melakukan tugasnya.
Christophe
Jadi secara semantik, tidak ada bedanya jika variabelnya konstan dan alamatnya tidak diambil. Sisa pertanyaannya adalah: mana yang harus Anda gunakan?
user253751
1

Variabel lokal diinisialisasi atau dibangun setiap kali fungsi dipanggil. Variabel lokal disimpan di stack dan karenanya umumnya aman untuk thread.

Variabel lokal statis diinisialisasi atau dibangun hanya sekali; pertama kali fungsi dipanggil. Variabel statis lokal tidak disimpan di tumpukan dan karenanya umumnya tidak aman untuk thread.

Variabel lokal const adalah variabel yang tidak berubah dan diinisialisasi atau dikonstruksikan setiap kali fungsi dipanggil. Variabel const lokal disimpan di stack dan karenanya umumnya aman untuk thread.

Variabel lokal const statis adalah variabel yang tidak berubah dan diinisialisasi atau dibangun hanya sekali; pertama kali fungsi dipanggil. Variabel const statis lokal tidak disimpan di stack dan karenanya umumnya tidak aman untuk thread.

Compiler mungkin dapat mengoptimalkan variabel const ke dalam konstanta waktu kompilasi.

Compiler mungkin dapat mengoptimalkan variabel-variabel non-statis dengan menyimpannya di register daripada di stack.

Theron W Genaux
sumber
Mengapa static constvariabel lokal tidak aman untuk thread? Nilai mereka konstan walaupun nilainya terletak di hep.
sandwich pemodelan terpadu
@unifiedmodelingsandwich: Bagaimana jika dua utas melakukan panggilan pertama ke fungsi secara bersamaan? Kemudian kedua utas akan mencoba menginisialisasi static constvariabel itu.
Bart van Ingen Schenau
Tidak di C ++ 11 mereka tidak mau. Inisialisasi dinamis statika fungsi-lokal aman-utas.
Sebastian Redl
@ BartartIngenSchenau Sejak C ++ 11, inisialisasi variabel lokal statis adalah thread-safe . A masih benar dalam mengatakan bahwa itu tidak aman secara umum , tetapi akan lebih akurat untuk mengatakan bahwa ini hanya kasus sebelum C ++ 11.
sandwich pemodelan terpadu
1
@unifiedmodelingsandwich: Terima kasih atas informasinya. Saya sebagian besar terjebak pada C ++ 03 :-(
Bart van Ingen Schenau