Penghentian kata kunci statis… tidak lebih?


89

Dalam C ++ dimungkinkan untuk menggunakan statickata kunci dalam unit terjemahan untuk mempengaruhi visibilitas simbol (baik variabel atau deklarasi fungsi).

Di n3092, ini sudah tidak digunakan lagi:

Lampiran D.2 [depr.static]
Penggunaan kata kunci statis tidak digunakan lagi saat mendeklarasikan objek dalam lingkup namespace (lihat 3.3.6).

Di n3225, ini telah dihapus.

Satu- satunya artikel yang dapat saya temukan agak informal.

Itu memang menggarisbawahi, bahwa untuk kompatibilitas dengan C (dan kemampuan untuk mengkompilasi program-C sebagai C ++) penghentian itu mengganggu. Namun, mengompilasi program C secara langsung sebagai C ++ bisa menjadi pengalaman yang membuat frustrasi, jadi saya tidak yakin apakah itu perlu dipertimbangkan.

Adakah yang tahu mengapa itu diubah?


3
Anda mendeklarasikan objek pada lingkup namespace di C?
Etienne de Martel

heh, thx, menemukan tempat untuk mendapatkannya. Mencoba menghapus komentar tetapi Anda mengalahkan saya di sana.
Edward Strange


1
Ini juga memberi Komite C ++ kesempatan untuk membatalkan sesuatu dalam versi Standar berikutnya :-)
James McNellis

Jawaban:


75

Dalam Laporan Cacat Bahasa Inti Standar C ++ dan Masalah yang Diterima, Revisi 94 di bawah 1012. Statis yang tidak berlaku lagi , mereka mencatat:

Meskipun 7.3.1.1 [namespace.unnamed] menyatakan bahwa penggunaan kata kunci statis untuk mendeklarasikan variabel dalam cakupan namespace tidak digunakan lagi karena namespace yang tidak disebutkan namanya menyediakan alternatif yang lebih baik, kecil kemungkinannya fitur tersebut akan dihapus kapan saja di masa mendatang .

Pada dasarnya mengatakan bahwa penghinaan statictidak masuk akal. Ini tidak akan pernah dihapus dari C ++, dan ini masih berguna karena Anda tidak memerlukan kode boilerplate yang Anda perlukan dengan namespace yang tidak bernama, jika Anda hanya ingin mendeklarasikan fungsi atau objek dengan tautan internal.


2
Yah, sepertinya penghentian akan mendorong orang untuk menggunakan namespace yang tidak disebutkan namanya, yang akan menjadi hal yang baik.
sbi

1
@unaperson: Jika tidak ada alasan lain, maka karena ruang nama tanpa nama menyediakan mekanisme yang sama untuk membuat variabel, konstanta, fungsi, dan jenis internal ke TU mereka. static class ... , OTOH, tidak akan berhasil.
sbi

2
@nbt: Karena Anda tidak dapat menggunakan simbol statis sebagai argumen template dan karena banyak pemula akan lebih mudah menggunakan statis dan kemudian tidak mencoba <functional> dan <algorithm> et al. Hanya berpikir sebentar.
Sebastian Mach

3
"karena Anda tidak memerlukan kode boilerplate yang Anda perlukan dengan namespace tanpa nama"? Apa "kode boilerplate"? Sesuatu di luar " namespace {" dan " }"?
towi

2
@ErikAronesty Jika Anda memiliki "kelas lokal" di file lain dengan nama yang sama maka Anda akan melakukan pelanggaran ODR.
LF

32

Saya akan mencoba untuk menjawab pertanyaan Anda, meskipun itu adalah pertanyaan lama, dan tidak terlihat sangat penting (sebenarnya tidak sangat penting dalam dirinya sendiri ), dan telah menerima jawaban cukup baik sudah. Alasan saya ingin menjawabnya adalah karena ini berkaitan dengan masalah mendasar evolusi standar dan desain bahasa ketika bahasa didasarkan pada bahasa yang ada: kapan fitur bahasa harus dihentikan, dihapus, atau diubah dengan cara yang tidak kompatibel?

Dalam C ++ dimungkinkan untuk menggunakan kata kunci statis dalam unit terjemahan untuk mempengaruhi visibilitas simbol (baik variabel atau deklarasi fungsi).

Keterkaitan itu sebenarnya.

Di n3092, ini sudah tidak digunakan lagi:

Penghentian menunjukkan:

  • The niat untuk menghapus beberapa fitur di masa depan; ini tidak berarti bahwa fitur yang tidak digunakan lagi akan dihapus pada revisi standar berikutnya, atau harus dihapus "segera", atau sama sekali. Dan fitur yang tidak digunakan lagi dapat dihapus pada revisi standar berikutnya.
  • Upaya formal untuk mencegah penggunaannya .

Poin terakhir ini penting. Meskipun tidak pernah ada janji resmi bahwa program Anda tidak akan rusak, terkadang diam-diam, oleh standar berikutnya, panitia harus berusaha menghindari pelanggaran kode yang "masuk akal". Penghentian harus memberi tahu programmer bahwa tidak masuk akal untuk bergantung pada beberapa fitur .

Itu memang menggarisbawahi, bahwa untuk kompatibilitas dengan C (dan kemampuan untuk mengkompilasi program-C sebagai C ++) penghentian itu mengganggu. Namun, mengompilasi program C secara langsung sebagai C ++ bisa menjadi pengalaman yang membuat frustrasi, jadi saya tidak yakin apakah itu perlu dipertimbangkan.

Sangat penting untuk mempertahankan subset umum C / C ++, terutama untuk file header. Tentu saja, staticdeklarasi global adalah deklarasi simbol dengan linkage internal dan ini tidak terlalu berguna dalam file header.

Tapi masalahnya bukan hanya kompatibilitas dengan C, itu juga kompatibilitas dengan C ++ yang ada: ada banyak program C ++ valid yang menggunakan staticdeklarasi global. Kode ini tidak hanya legal secara formal, tetapi juga masuk akal, karena menggunakan fitur bahasa yang terdefinisi dengan baik seperti yang dimaksudkan untuk digunakan .

Hanya karena sekarang ada "cara yang lebih baik" (menurut beberapa) untuk melakukan sesuatu tidak membuat program yang ditulis dengan cara lama "buruk" atau "tidak masuk akal". Kemampuan menggunakan statickata kunci pada deklarasi objek dan fungsi pada lingkup global dipahami dengan baik di komunitas C dan C ++, dan paling sering digunakan dengan benar.

Dengan nada yang sama, saya tidak akan mengubah model C doublemenjadi static_cast<double>hanya karena "C-style cast buruk", karena static_cast<double>menambahkan informasi nol dan keamanan nol.

Gagasan bahwa setiap kali cara baru untuk melakukan sesuatu ditemukan, semua programmer akan buru-buru menulis ulang kode kerja mereka yang sudah terdefinisi dengan baik adalah gila. Jika Anda ingin menghapus semua keburukan dan masalah C yang diwariskan, Anda tidak mengubah C ++, Anda menciptakan bahasa pemrograman baru. Menghapus setengah satu penggunaan statichampir tidak membuat C ++ kurang C-jelek.

Perubahan kode membutuhkan pembenaran, dan "lama itu buruk" tidak pernah menjadi pembenaran untuk perubahan kode.

Pemutusan perubahan bahasa membutuhkan pembenaran yang sangat kuat. Menyederhanakan bahasa ini tidak pernah menjadi pembenaran untuk perubahan besar.

Alasan yang diberikan mengapa staticburuk hanya sangat lemah, dan bahkan tidak jelas mengapa deklarasi objek dan fungsi tidak digunakan bersama-sama - memberi mereka perlakuan yang berbeda hampir tidak membuat C ++ lebih sederhana atau lebih ortogonal.

Jadi, sungguh, ini adalah kisah yang menyedihkan. Bukan karena konsekuensi praktis yang dimilikinya: ia sama sekali tidak memiliki konsekuensi praktis. Tapi karena itu menunjukkan kurangnya akal sehat dari panitia ISO.


5
Seperti yang Anda sendiri tunjukkan, tujuan mencela kata itu adalah untuk mencegah penggunaannya. Namun Anda tidak membuat argumen bahwa melarang penggunaannya adalah salah. Saya tentu berharap tidak ada orang di luar sana yang mendorong orang untuk menggunakan deklarasi statis bercakupan namespace melalui namespace anonim. Tidak, kecuali mereka secara khusus perlu mengkompilasi silang C.
Nicol Bolas

2
Saya tidak terlalu peduli tentang orang-orang yang menggunakan cakupan global staticatau ruang nama anonim, saya juga tidak menyemangati atau mengecilkan hati. Maksud saya adalah jika Anda benar-benar ingin mencegah orang menggunakan ruang nama anonim, Anda harus memberi mereka argumen yang baik. Dalam praktiknya, saya yakin bahwa di sebagian besar entitas implementasi yang dideklarasikan dalam namespace tanpa nama adalah simbol yang diekspor dengan nama acak, sehingga tabel ekspor akan bertambah. Entitas yang dideklarasikan sebagai static, OTOH, tidak diekspor dengan cara apa pun. Dengan demikian banyak orang memilih, berdasarkan pengamatan itu, untuk digunakan static.
penasaran

2
Seperti yang Anda sendiri tunjukkan, tujuan mencela kata itu adalah untuk mencegah penggunaannya. ” Maksud dari mengecilkan hati penggunaannya adalah bahwa itu mungkin hilang suatu hari nanti. Maksud saya adalah bahwa namespace-scope statictidak akan pernah hilang, jadi salah untuk mencabutnya. " Namun Anda tidak membuat argumen bahwa melarang penggunaannya adalah salah. " Saya tidak melihat argumen yang meyakinkan yang menunjukkan bahwa penggunaan namespace-scope staticadalah "salah". Mencela itu hanya untuk mencegah penggunaannya adalah salah, karena tidak ada yang benar-benar percaya itu akan hilang, dan karena tidak meyakinkan orang bahwa menggunakannya adalah "salah".
penasaran

5
Seluruh bahasa akan "hilang suatu hari nanti". Mari kita hentikan C ++.
Balapan Ringan di Orbit

2
"Dengan nada yang sama, saya tidak akan mengubah cast gaya-C menjadi dua kali lipat menjadi static_cast <double> hanya karena" cast gaya-C buruk ", karena static_cast <double> menambahkan informasi nol dan keamanan nol." Pertarungan abadi saya dengan banyak insinyur perangkat lunak yang terus mengeluh tentang penggunaan sembarang gaya C cast dari satu primitif ke yang lain.
Makogan

14

Tidak berlaku lagi atau tidak, menghapus fitur bahasa ini akan merusak kode yang ada dan mengganggu orang.

Keseluruhan depresiasi statis hanyalah angan-angan di sepanjang baris "ruang nama anonim lebih baik daripada statis" dan "referensi adalah petunjuk yang lebih baik". Lol.


1
"Referensi adalah petunjuk yang lebih baik"? Tidak, petunjuk cerdas adalah petunjuk yang lebih cerdas. Anda tidak dapat menggunakan referensi untuk memori yang dialokasikan dari heap, err, free store.
Dan Breslau

3
Maaf, saya lupa mengakhirinya dengan senyum ironis.
Maxim Egorushkin

2
@ Dan: Itulah yang dikatakan jawaban ini: "angan-angan" di sepanjang garis pemikiran yang salah yang serupa. Namespace tanpa nama adalah fitur penting, seperti global-scope-static, meskipun untuk alasan yang sedikit berbeda, dan meskipun memiliki beberapa tumpang tindih dalam penerapan.
Fred Nurk

@Fred, @Maxim: Maaf jika saya salah paham, atau jika ingatan saya salah. Tapi saya tidak mengkategorikan "referensi adalah petunjuk yang lebih baik" sebagai ekuivalen dengan "ruang nama anonim lebih baik daripada statis" sebagai kasus angan-angan. Saya sangat menyadari upaya untuk membuat yang terakhir tetap, tetapi saya tidak ingat ada yang membuat proposal serius untuk mengganti petunjuk dengan referensi. Sekali lagi, mungkin kesadaran saya sendiri yang kurang.
Dan Breslau

1
@DanBreslau: char* foo = new char; char& ref = *foo;Hanya karena Anda diberi penunjuk pada awalnya tidak mengatakan apa pun tentang kemampuan Anda untuk menggunakan referensi.
Balapan Ringan di Orbit
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.