C ++ semantik `const statis` vs` const`

149

Khususnya di C ++, apa perbedaan semantik antara misalnya:

static const int x = 0 ;

dan

const int x = 0 ;

untuk keduanya staticsebagai penghubung dan specifier kelas penyimpanan (yaitu di dalam dan di luar fungsi).

Clifford
sumber
7
staticmungkin kata kunci yang paling banyak dimuat di C ++. Arti kode Anda sangat bervariasi tergantung pada apakah itu di lingkup namespace, di lingkup kelas, atau di lingkup fungsi. Anda mungkin ingin mengklarifikasi itu.
sbi
1
@ Sbi: Saya pikir sudah melakukannya. Ruang lingkup fungsi (di mana itu adalah specifier kelas penyimpanan) dan lingkup file (di mana itu adalah specifier tautan). Variabel anggota ruang kelas dan ruang lingkup namespace secara khusus tidak menjadi perhatian saya sehubungan dengan pertanyaan ini, meskipun jika ada yang merasa ada perbedaan yang menarik, jangan ragu untuk membahasnya juga.
Clifford
@Clifford: Maaf saya mengabaikan kata-kata terakhir itu. Namun, ini mengungkapkan kesalahpahaman di pihak Anda: Di C ++, cakupan file adalah lingkup namespace. Jika Anda mendeklarasikan sesuatu di luar namespace, itu hanya akan menjadi milik namespace global (dan dapat diakses melalui awalan ::tanpa pengenal di depan). Saya tidak mengetahui adanya perbedaan yang berarti antara namespace global dan namespace yang bersarang di dalamnya. Tentu saja tidak ada staticbenda terkait .
sbi
1
linkage berbeda dari visibilitas , dengan menggunakannya secara bergantian Anda akan membingungkan orang yang Anda ajak bicara dan mungkin juga diri Anda sendiri.
Ben Voigt
1
@ Ben, @sbi: Saya tidak bermaksud menyarankan bahwa ruang lingkup file dan tautan statis adalah sama, hanya bahwa tautan statis menyiratkan ruang lingkup file. Dalam hal ini, ruang lingkup (atau visibilitas) adalah atribut tautan statis dan eksternal, bukan sinonim untuk keduanya. Saya merasa bahwa pertanyaan awal tetap jelas dan terbentuk dengan baik, dan bahwa kami hanya mendiskusikan komentar yang dibuat sebagai tanggapan terhadap komentar sbi yang agak merendahkan. Kami membahas semantik bahasa Inggris yang tidak tepat di sini daripada pemahaman saya, jadi saya pikir kita bisa berhenti.
Clifford

Jawaban:

128

Pada lingkup file, tidak ada perbedaan dalam C ++. constmenjadikan tautan internal sebagai default, dan semua variabel global memiliki masa pakai statis. Tetapi varian pertama memiliki perilaku yang sama dalam C, sehingga mungkin menjadi alasan yang baik untuk menggunakannya.

Dalam suatu fungsi, versi kedua dapat dihitung dari parameter. Dalam C atau C ++ tidak harus berupa konstanta waktu kompilasi seperti yang dibutuhkan beberapa bahasa lain.

Di dalam kelas, pada dasarnya hal yang sama untuk fungsi. constNilai instance dapat dihitung dalam ctor-initializer-list . A static constdiatur selama inisialisasi startup dan tetap tidak berubah selama sisa program. (Catatan: kode untuk staticanggota terlihat sedikit berbeda karena deklarasi dan inisialisasi dipisahkan.)

Ingat, dalam C ++, constberarti hanya-baca , tidak konstan . Jika Anda memiliki pointer-to- constmaka bagian lain dari program ini dapat mengubah nilai saat Anda tidak melihat. Jika variabel didefinisikan dengan const, maka tidak ada yang bisa mengubahnya setelah inisialisasi tetapi inisialisasi masih bisa rumit.

Ben Voigt
sumber
1
Apakah ada yang disebut ruang lingkup file? Saya baru saja memeriksa $ 3,3 dan saya pikir yang terdekat adalah 'lingkup namespace'. Apakah pemahaman saya benar? Standar C ++ 03 menyebutkan ruang lingkup file hanya di Appendices
Chubsdad
2
Saya menyarankan bahwa ruang lingkup file adalah artefak dari linker daripada kompiler, jadi mungkin tidak mendapatkan banyak perhatian dalam standar bahasa. Mungkin ini adalah "kompilasi unit scope".
Clifford
8
+1 untuk frasa "const berarti hanya-baca, tidak konstan", yaitu, "Kompiler, jika Anda melihat seseorang mencoba mengubah hal const ini, gonggong sangat keras." Ini adalah alasan sesuatu bisa menjadi stabil & volatile pada saat bersamaan.
Dan
5
Ini lebih "Kompiler, jika Anda melihat saya mencoba untuk memodifikasi hal const ini (atau memberikan izin orang lain untuk melakukannya)", gonggong sangat keras. Dalam sebagian besar konteks, constberlaku untuk tampilan variabel dan bukan variabel itu sendiri, orang lain dapat memiliki non- constview dari variabel yang sama, dan kompiler akan sangat diam ketika mereka memodifikasinya.
Ben Voigt
1
@ Ben: Hanya untuk memperjelas, C ++ 0x tidak menghapus penggunaan khusus itu const, tetapi yang baru constexprdapat digunakan sebagai gantinya (dan dalam skenario lain juga). Sebenarnya, standar C ++ 0x memperluas kemampuan untuk digunakan constdalam skenario itu untuk "tipe literal" yang tidak terpisahkan juga. Saya pikir saya lebih suka menggunakan constexpruntuk kasus-kasus itu, karena Anda akan melanggar kompatibilitas dengan pre-C ++ 0x kompiler pula.
Michael Burr
4

C ++ 17 draft standar pada constmenyiratkan staticpada lingkup file

Ini adalah kutipan untuk apa yang disebutkan di: https://stackoverflow.com/a/3709257/895245

C ++ 17 n4659 konsep standar 6.5 "Program dan tautan":

3 Nama yang memiliki lingkup namespace (6.3.6) memiliki hubungan internal jika itu adalah nama

  • (3.1) - variabel, fungsi atau templat fungsi yang secara eksplisit dinyatakan statis; atau,
  • (3.2) - variabel non-inline dari tipe const-kualifikasi non-volatil yang tidak secara eksplisit dinyatakan eksternal atau sebelumnya dinyatakan memiliki hubungan eksternal; atau
  • (3.3) - anggota data dari serikat anonim.

Lampiran C (informatif) Kompatibilitas, C.1.2 Klausul 6: "konsep dasar" memberikan alasan mengapa ini diubah dari C:

6.5 [juga 10.1.7]

Ubah: Nama ruang lingkup file yang secara eksplisit dinyatakan const, dan tidak secara eksplisit dinyatakan extern, memiliki tautan internal, sedangkan di C akan memiliki tautan eksternal.

Dasar Pemikiran: Karena objek const dapat digunakan sebagai nilai selama terjemahan dalam C ++, fitur ini mendesak pemrogram untuk menyediakan inisialisasi eksplisit untuk setiap objek const. Fitur ini memungkinkan pengguna untuk meletakkan objek const dalam file sumber yang termasuk dalam lebih dari satu unit terjemahan.

Efek pada fitur asli: Ubah ke semantik fitur yang terdefinisi dengan baik.

Kesulitan mengkonversi: Transformasi semantik.

Seberapa luas digunakan: Jarang.

Lihat juga: Mengapa const menyiratkan hubungan internal dalam C ++, padahal tidak dalam C?

Apa yang Anda mungkin ingin lakukan sebagai ganti header

Dijelaskan secara rinci di: Apa arti 'const static' dalam C dan C ++?

  • pre C ++ 17: externdi header, definisi dalam file cpp
  • posting C ++ 17: variabel inline pada header
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
Terima kasih, meskipun saya tidak berpikir ini adalah kesempatan di C ++ 17 dibandingkan bahkan dengan C ++ 98, dan pertanyaannya ditanyakan pada tahun 2010. Selain itu, jawaban Anda hanya berurusan dengan statis sebagai specifier tautan (pada lingkup namespace) , dan pertanyaan yang diajukan secara khusus tentang semantik dalam konteks yang berbeda.
Clifford
@ Clifford ya, pasti lebih tua dari C ++ 17, hanya malas membaca semua standar ;-) Akan memperjelas bagian ruang lingkup file.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功