Apakah variabel global buruk? [Tutup]

247

Dalam C / C ++, apakah variabel global seburuk yang menurut profesor saya?

GEOCHET
sumber
17
Saya akan gigit kalau-kalau dia mencoba menceritakan lelucon ... "seberapa buruk mereka"?
Zach Scrivena
13
Saya pikir pertanyaan ini cukup menarik! Pengembangan perangkat lunak masih menghadapi perangkap lama yang sama sejak awal dan programmer sering masih tidak tahu bahwa menggunakan variabel global, gotos, variabel bernama pendek BUKAN masalah. Kode buruk ditulis setiap hari tanpa menggunakannya. +1
Sylvain Rodrigue
69
Bagaimana kita bisa menjawab? Dia belum memberi tahu kami seberapa buruk menurut profesornya. :)
Steve Fallows
9
@Juan Mendes Saya 100% setuju dengan Anda! Masalah yang saya bicarakan adalah bahwa banyak pengembang tahu bahwa mereka tidak boleh menggunakan variabel global tetapi mereka tidak tahu mengapa! Dan dengan demikian saya telah melihat banyak perangkat lunak besar di mana masing-masing dan setiap fungsi menerima struktur mega yang sama yang berisi +100 bidang - Lihat bu, tidak ada variabel global! Masalah yang sama dengan apa yang disebut "praktik yang baik": mereka adalah praktik yang baik dalam beberapa konteks, bukan dalam semua konteks. Menggunakannya MUNGKIN membuat kode yang tidak dapat dipelihara. Bersulang.
Sylvain Rodrigue
3
Ada sangat sedikit kegunaan baik untuk variabel global. Satu kemungkinan, tetapi penggunaan yang dapat diperdebatkan, akan menjadi objek "konfigurasi" global, yang membaca dalam file konfigurasi satu kali saat startup.
Siler

Jawaban:

256

Masalah dengan variabel global adalah karena setiap fungsi memiliki akses ke ini, menjadi semakin sulit untuk mengetahui fungsi mana yang benar-benar membaca dan menulis variabel-variabel ini.

Untuk memahami cara kerja aplikasi, Anda harus memperhitungkan setiap fungsi yang mengubah kondisi global. Itu bisa dilakukan, tetapi seiring pertumbuhan aplikasi itu akan semakin sulit sampai hampir tidak mungkin (atau setidaknya membuang-buang waktu).

Jika Anda tidak bergantung pada variabel global, Anda dapat melewati keadaan di antara berbagai fungsi sesuai kebutuhan. Dengan begitu, Anda memiliki peluang yang jauh lebih baik untuk memahami apa fungsi masing-masing, karena Anda tidak perlu memperhitungkan kondisi global.

Brian Rasmussen
sumber
9
Jawaban ini sangat bagus. Kombinasikan ini dengan 'meminimalkan ruang lingkup variabel' jawaban stackoverflow.com/questions/357187/...
bobobobo
17
Ganti 'kelas' untuk 'aplikasi' dan 'status objek' untuk 'keadaan global' dan Anda membuat argumen yang persis sama untuk tidak menggunakan variabel anggota (alias bidang) di kelas. Jawaban sebenarnya adalah menggunakannya saat yang tepat.
Ian Goldby
2
Beberapa pertanyaan (mungkin konyol): 1) Jika Anda ingin mengetahui fungsi mana yang membaca dan menulis variabel-variabel ini, tidak bisakah Anda menggunakan fungsi "find" di editor untuk menemukan kasus-kasus di mana nilai-nilai dalam variabel ini diubah? 2) "Itu bisa dilakukan, ... buang-buang waktu saja)." Bisakah Anda memberi contoh? 3) "Jika Anda tidak bergantung pada variabel global, ... Anda tidak perlu memperhitungkan kondisi global." Saya tidak mengerti bagaimana itu merupakan keuntungan. Mungkin contoh itu akan berhasil untuk saya.
Andrei
2
@bobobobo broken link, bisakah kami mendapatkan tangkapan layar dari Anda, pengguna 10k +?
noɥʇʎԀʎzɐɹƆ
3
@ noɥʇʎԀʎzɐɹƆ Ini dia! i.imgur.com/RwRgJLZ.jpg
Mateen Ulhaq
85

Yang penting adalah mengingat tujuan keseluruhan: kejelasan

Aturan "tidak ada variabel global" ada di sana karena sebagian besar waktu, variabel global membuat makna kode kurang jelas.

Namun, seperti banyak aturan, orang ingat aturan itu, dan bukan apa aturan itu dimaksudkan untuk dilakukan.

Saya telah melihat program yang tampaknya menggandakan ukuran kode dengan melewatkan sejumlah besar parameter di sekitar hanya untuk menghindari kejahatan variabel global. Pada akhirnya, menggunakan global akan membuat program lebih jelas bagi mereka yang membacanya. Dengan mengikuti kata aturan tanpa berpikir, programmer asli telah gagal maksud aturan.

Jadi, ya, global sering kali buruk. Tetapi jika Anda merasa bahwa pada akhirnya, niat programmer dibuat lebih jelas dengan menggunakan variabel global, maka silakan. Namun, ingat kejernihan yang terjadi secara otomatis ketika Anda memaksa seseorang untuk mengakses potongan kode kedua (global) untuk memahami cara kerja potongan pertama.

Tom West
sumber
8
Menyarankan menggunakan variabel global alih-alih lewat adalah resep untuk membuat kode Anda tidak dapat digunakan kembali, dan tidak aman untuk multi-threading
Juan Mendes
16
Menyarankan global dalam keadaan yang tepat adalah resep untuk kode yang lebih jelas dan berkinerja lebih tinggi. "Passing" memerlukan alokasi memori dinamis tumpukan konstan, dan ini akan konyol untuk sesuatu yang seharusnya menjadi global, seperti buffer global untuk data soket yang masuk. Misalnya, jika Anda memiliki fungsi yang membaca Winsock recv (), mengapa terus-menerus membuat dan membatalkan alokasi buffer ini dalam setiap panggilan? Jadikan buffer sebagai global. Beberapa utas tidak akan membacanya.
James
Hanya ingin tahu, program apa yang menggandakan ukuran kode dengan melewatkan parameter untuk menghindari variabel global? Dalam pengalaman saya, menggunakan variabel global dapat memecahkan masalah paparan data, tetapi biasanya ada logika kompleks tambahan yang perlu Anda tambahkan untuk memastikan variabel magis ini berperilaku baik.
user2167582
3
Jika seseorang melewati sekitar 100 variabel, maka mereka tidak mengetahui apa itu objek. Menggunakan referensi ke objek ini kemudian paling buruk melewati pointer. Saya akan mengatakan bahwa aturannya bukan hanya kejelasan, tetapi juga kemampuan uji coba - dan menggunakan non-global cenderung membuat banyak hal lebih mudah untuk diuji.
UKMonkey
2
"Jika seseorang melewati sekitar 100 variabel, maka mereka belum mengetahui apa objek itu." Setuju, tetapi tidak semua dunia berorientasi objek. Contoh pribadi saya menggandakan ukuran kode adalah program besar Fortran, sekitar tahun 1986. Sebagai karyawan baru di universitas, saya "memperbaikinya", dengan menambahkan sekitar 30 parameter untuk setiap panggilan, menghilangkan semua global. Kemudian membuka kancing perbaikan saya ketika saya menyadari apa yang telah saya tempa.
Tom West
64

Dosen saya biasa mengatakan sesuatu seperti: menggunakan variabel global tidak masalah jika Anda menggunakannya dengan benar. Saya pikir saya tidak pernah bisa menggunakannya dengan benar, jadi saya jarang menggunakannya sama sekali.

barneytron
sumber
25
Benar sekali. Mereka seperti gotos, jika Anda tidak tahu kapan menggunakannya maka jangan pernah melakukannya.
David Holm
5
Di perusahaan saya saat ini, mereka banyak menggunakan staticvariabel global, bahasa C. Terbatas pada unit terjemahan yang relatif kecil, mereka mulai menyerupai variabel kelas objek C ++.
Vorac
1
Variabel statis @Vacac bukan variabel global, mereka adalah variabel lokal. Variabel global adalah variabel yang tersedia di mana-mana dalam program (karenanya "global", ya). Jangan bingung dengan variabel lingkup file , yang merupakan variabel yang dinyatakan di luar fungsi apa pun. Variabel ruang lingkup file statis bukan variabel global.
Lundin
1
Untuk memperbaiki diri sendiri program lifetime, file scope variables,. Dan mereka menjadi sangat global setelah Anda memberikan pointer ke variabel ke dunia luar (yang tidak mungkin dengan variabel otomatis) ..
Vorac
@Lundin Saya setuju, staticVariabel global memiliki cakupan terbatas untuk unit terjemahan yang sama. Tetapi mereka memiliki seumur hidup sampai akhir program sebagai variabel global.
akhilesh1988
38

Variabel global hanya boleh digunakan ketika Anda tidak memiliki alternatif. Dan ya, itu termasuk lajang. 90% dari waktu, variabel global diperkenalkan untuk menghemat biaya melewati parameter. Dan kemudian multithreading / unit testing / maintenance coding terjadi, dan Anda memiliki masalah.

Jadi ya, dalam 90% situasi variabel global buruk. Pengecualian tidak akan terlihat oleh Anda di tahun-tahun kuliah Anda. Satu pengecualian yang bisa saya pikirkan adalah kepala saya berurusan dengan objek global yang inheren seperti tabel interupsi. Hal-hal seperti koneksi DB tampaknya bersifat global, tetapi tidak.


sumber
2
Satu-satunya pengecualian yang saya lihat di tahun-tahun kuliah saya adalah fungsi panggil kembali grafis. Di XWindows, mouse-callback tidak memiliki argumen * data yang batal yang memungkinkan Anda untuk melewati potongan-potongan keadaan program yang sewenang-wenang ... (bukan berarti BANYAK lebih baik daripada global ...)
Brian Postow
10
+1 untuk "Hal-hal seperti koneksi DB tampaknya bersifat global, tetapi tidak."
R .. GitHub BERHENTI MEMBANTU ICE
1
Tabel interupsi tidak bersifat global, ada satu per prosesor - tetapi ada juga satu contoh program Anda per prosesor sehingga "dibatalkan".
user253751
1
Adakah yang bisa menjelaskan mengapa koneksi DB tidak bersifat global (dan apa yang akan menjadi alternatif yang baik)? Saya selalu menganggap koneksi sebagai salah satu kasus langka di mana global dapat diterima.
Floella
33

Masalah yang diciptakan variabel global untuk pemrogram adalah memperluas variabel antar-komponen permukaan antara berbagai komponen yang menggunakan variabel global. Ini artinya bahwa seiring meningkatnya jumlah komponen yang menggunakan variabel global, kompleksitas interaksi juga dapat meningkat. Peningkatan kopling ini biasanya membuat cacat lebih mudah untuk disuntikkan ke sistem ketika membuat perubahan dan juga membuat cacat lebih sulit untuk didiagnosis dan diperbaiki. Peningkatan kopling ini juga dapat mengurangi jumlah opsi yang tersedia saat membuat perubahan dan dapat meningkatkan upaya yang diperlukan untuk perubahan karena sering kali seseorang harus menelusuri berbagai modul yang juga menggunakan variabel global untuk menentukan konsekuensi dari perubahan.

Tujuan enkapsulasi , yang pada dasarnya kebalikan dari menggunakan variabel global, adalah untuk mengurangi kopling untuk membuat pemahaman dan mengubah sumber lebih mudah dan lebih aman dan lebih mudah diuji. Jauh lebih mudah untuk menggunakan pengujian unit ketika variabel global tidak digunakan.

Misalnya jika Anda memiliki variabel integer global sederhana yang sedang digunakan sebagai indikator yang disebutkan bahwa berbagai komponen digunakan sebagai mesin negara dan Anda kemudian membuat perubahan dengan menambahkan status baru untuk komponen baru, Anda kemudian harus menelusuri semua yang lain komponen untuk memastikan bahwa perubahan tidak akan memengaruhi mereka. Contoh masalah yang mungkin terjadi adalah jika switchpernyataan untuk menguji nilai variabel global enumerasi dengan casepernyataan untuk masing-masing nilai saat ini sedang digunakan di berbagai tempat dan kebetulan beberapa switchpernyataan tidak memiliki defaultkasus untuk ditangani. nilai tak terduga untuk global, tiba-tiba Anda memiliki perilaku yang tidak terdefinisi sejauh menyangkut aplikasi.

Di sisi lain, penggunaan area data bersama mungkin digunakan untuk berisi sekumpulan parameter global yang dirujuk di seluruh aplikasi. Pendekatan ini sering digunakan dengan aplikasi tertanam dengan jejak memori kecil.

Ketika menggunakan variabel global dalam aplikasi semacam ini biasanya tanggung jawab untuk menulis ke area data dialokasikan ke satu komponen dan semua komponen lainnya melihat area sebagai constdan membaca darinya, tidak pernah menulis ke sana. Mengambil pendekatan ini membatasi masalah yang bisa berkembang.

Beberapa masalah dari variabel global yang perlu ditangani

Ketika sumber untuk variabel global seperti struct dimodifikasi, semua yang menggunakannya harus dikompilasi ulang sehingga semua yang menggunakan variabel tahu ukuran sebenarnya dan templat memori.

Jika lebih dari satu komponen dapat memodifikasi variabel global Anda dapat mengalami masalah dengan data yang tidak konsisten berada di variabel global. Dengan aplikasi multi-threading, Anda mungkin perlu menambahkan semacam penguncian atau wilayah kritis untuk memberikan cara sehingga hanya satu utas pada satu waktu dapat memodifikasi variabel global dan ketika utas memodifikasi variabel, semua perubahan selesai dan dilakukan sebelum utas lainnya dapat meminta variabel atau memodifikasinya.

Debugging aplikasi multi-utas yang menggunakan variabel global bisa lebih sulit. Anda dapat mengalami kondisi balapan yang dapat membuat cacat yang sulit untuk ditiru. Dengan beberapa komponen yang berkomunikasi melalui variabel global, terutama dalam aplikasi multi-ulir, dapat mengetahui komponen apa yang mengubah variabel kapan dan bagaimana itu mengubah variabel bisa sangat sulit untuk dipahami.

Nama clash bisa menjadi masalah dengan penggunaan variabel global. Variabel lokal yang memiliki nama yang sama dengan variabel global dapat menyembunyikan variabel global. Anda juga mengalami masalah konvensi penamaan saat menggunakan bahasa pemrograman C. Cara mengatasinya adalah membagi sistem menjadi sub-sistem dengan variabel global untuk sub-sistem tertentu yang semuanya dimulai dengan tiga huruf pertama yang sama (lihat ini untuk menyelesaikan tabrakan ruang nama pada tujuan C ). C ++ menyediakan ruang nama dan dengan C Anda dapat menyiasatinya dengan membuat struct yang dapat dilihat secara global yang anggotanya adalah berbagai item data dan penunjuk ke data dan fungsi yang disediakan dalam file sebagai statis karenanya dengan visibilitas file hanya sehingga mereka hanya dapat dirujuk melalui struct yang terlihat secara global.

Dalam beberapa kasus, niat aplikasi asli diubah sehingga variabel global yang menyediakan status untuk utas tunggal dimodifikasi untuk memungkinkan beberapa utas duplikat dijalankan. Contohnya adalah aplikasi sederhana yang dirancang untuk pengguna tunggal menggunakan variabel global untuk negara dan kemudian permintaan turun dari manajemen untuk menambahkan antarmuka REST untuk memungkinkan aplikasi jarak jauh untuk bertindak sebagai pengguna virtual. Jadi sekarang Anda harus menduplikasi variabel global dan informasi statusnya sehingga pengguna tunggal dan setiap pengguna virtual dari aplikasi jarak jauh memiliki variabel global mereka sendiri yang unik.

Menggunakan C ++ namespacedan structTeknik untuk C

Untuk bahasa pemrograman C ++, namespacearahan adalah bantuan besar dalam mengurangi kemungkinan bentrokan nama. namespacebersama dengan classdan berbagai kata kunci akses ( private, protected, dan public) menyediakan sebagian besar perangkat yang diperlukan untuk variabel encapsulate. Namun bahasa pemrograman C tidak memberikan arahan ini. Posting stackoverflow ini, Namespaces di C , menyediakan beberapa teknik untuk C.

Teknik yang bermanfaat adalah memiliki area data residen memori tunggal yang didefinisikan sebagai structyang memiliki visibilitas global dan dalam hal ini structadalah petunjuk untuk berbagai variabel global dan fungsi yang diekspos. Definisi aktual dari variabel global diberikan lingkup file menggunakan statickata kunci. Jika Anda kemudian menggunakan constkata kunci untuk menunjukkan yang hanya baca, kompiler dapat membantu Anda untuk menegakkan akses hanya baca.

Menggunakan structteknik ini juga dapat merangkum global sehingga menjadi semacam paket atau komponen yang kebetulan global. Dengan memiliki komponen semacam ini, menjadi lebih mudah untuk mengelola perubahan yang memengaruhi fungsi global dan penggunaan global.

Namun sementara namespaceatau structteknik ini dapat membantu mengelola bentrokan nama, masalah mendasar dari penggabungan antar-komponen yang diperkenalkan oleh penggunaan global terutama dalam aplikasi multi-threaded modern, masih ada.

Richard Chambers
sumber
Ini adalah exaplanation terbaik yang dijatuhkan, menjelaskan segala yang ada padanya. Pujian!
johndoevodka
Bahasa Anda harus memiliki aturan kode untuk menghentikan Anda menggunakan terlalu banyak kopling kelas.
Pengembang Melbourne
20

Variabel global sama buruknya dengan Anda membuatnya, tidak kurang.

Jika Anda membuat program yang sepenuhnya dienkapsulasi, Anda dapat menggunakan global. Adalah "dosa" untuk menggunakan global, tetapi memprogram dosa adalah filosofis.

Jika Anda memeriksa L.in.oleum , Anda akan melihat bahasa yang variabelnya hanya global. Ini tidak dapat dihilangkan karena semua perpustakaan tidak punya pilihan selain menggunakan global.

Yang mengatakan, jika Anda punya pilihan, dan dapat mengabaikan filosofi programmer, global tidak terlalu buruk.

Tidak juga Gotos, jika Anda menggunakannya dengan benar.

Masalah besar "buruk" adalah bahwa, jika Anda salah menggunakannya, orang-orang berteriak, mars lander crash, dan dunia meledak .... atau sesuatu seperti itu.

pengguna54650
sumber
16
Mengecilkan masalah menggunakan global untuk siswa yang bingung bukanlah ide yang baik IMO.
GEOCHET
3
Filsafat Desain tidak objektif. Sama sekali tidak. Hanya karena sebagian besar programmer tidak menyukai sesuatu, tidak berarti orang tidak boleh melihat sesuatu itu. Sangat mudah untuk membuat penggunaan global secara umum tanpa akhir dunia. Biarkan dia melakukannya, berjuang (tahu dia akan), dan belajar caranya.
user54650
7
Kaya itu benar. Jawaban ini tidak mengatakan apa-apa tentang apa yang / tidak buruk (atau bagaimana global dapat digunakan dengan aman), hanya bahwa "mereka tidak seburuk semua itu. Karena itu, hanya meremehkan masalah.
jalf
4
Saya tidak setuju bahwa variabel global hanya "seburuk yang Anda buat". Saya pikir salah satu masalah utama, terutama dalam dunia multi-pengembang ini, yang saling terhubung, yang sebagian besar dari kita tinggal, bekerja, dan program, adalah bahwa variabel global memberi seseorang kesempatan lain untuk membuat kode Anda buruk.
gariepy
@ gariepy sampai saya tahu pembicaraannya tentang statika: D ok jadi begitu ... dan aplikasi saya hanya punya satu atau dua variabel global, yang satu dilengkapi dengan Visual Studio, DEBUG dan TRACE yang biasanya tidak kita gunakan: D
deadManN
19

Ya, tetapi Anda tidak dikenakan biaya variabel global sampai Anda berhenti bekerja dalam kode yang menggunakan variabel global dan mulai menulis sesuatu yang lain yang menggunakan kode yang menggunakan variabel global. Tetapi biayanya masih ada.

Dengan kata lain, ini adalah biaya tidak langsung jangka panjang dan oleh karena itu kebanyakan orang berpikir itu tidak buruk.

MSN
sumber
19

Jika mungkin kode Anda akan berakhir di bawah tinjauan intensif selama persidangan Mahkamah Agung , maka Anda ingin memastikan untuk menghindari variabel global.

Lihat artikel ini: Kode breathalyzer Buggy mencerminkan pentingnya ulasan sumber

Ada beberapa masalah dengan gaya kode yang diidentifikasi oleh kedua studi. Salah satu masalah gaya yang menyangkut pengulas adalah penggunaan ekstensif variabel global yang tidak dilindungi . Ini dianggap sebagai bentuk yang buruk karena meningkatkan risiko bahwa keadaan program akan menjadi tidak konsisten atau bahwa nilai-nilai akan secara tidak sengaja dimodifikasi atau ditimpa. Para peneliti juga menyatakan beberapa kekhawatiran tentang fakta bahwa presisi desimal tidak dijaga secara konsisten di seluruh kode.

Saya yakin para pengembang itu berharap mereka tidak menggunakan variabel global!

Casey
sumber
6
Itu adalah tawa terbaik yang pernah saya alami. Contoh nyata mengapa pengembangan sumber tertutup untuk untung adalah buruk, dan contoh yang baik dari vars global salah!
Evil Spork
Apa yang ditetapkan di sini adalah bahwa variabel global dipandang dengan cemoohan. Tidak ada apa pun di sini yang menunjukkan bahwa variabel global adalah masalah asli dalam kode. SysTest mengatakan bahwa sementara kode itu "tidak ditulis dengan cara yang konsisten dengan praktik terbaik desain perangkat lunak biasa", bahwa kode itu masih "dapat diandalkan menghasilkan hasil pengujian yang konsisten." Jadi tidak ada kerugian dari global yang benar-benar didokumentasikan. Seperti yang saya lihat, mereka baru saja menetapkan bahwa, "Ya, para dev ini tidak mempraktikkan agama pengkodean yang sama dengan dunia mainstream lainnya."
LionKimbro
17

Saya akan menjawab pertanyaan ini dengan pertanyaan lain: Apakah Anda menggunakan singeltons / Apakah singeltons buruk?

Karena (hampir semua) penggunaan singelton adalah variabel global yang dimuliakan.

Gavin Miller
sumber
11
Saya baru saja akan mengirim komentar cerdas yang mengatakan, "Mereka hanya buruk jika Anda memanggil mereka global, bukan lajang", tetapi Anda mengalahkan saya untuk itu.
smo
Saya masih mencoba mencari tahu apa itu LOL.
GeoffreyF67
1
@ Geoffrey: berikut adalah beberapa deskripsi SO yang bagus - stackoverflow.com/questions/11831/… dan untuk beberapa tautan bagus: stackoverflow.com/questions/11831/…
Gavin Miller
10
Sebagai catatan, singleton adalah variabel global dengan nama Pattern Design (tm) (lol) yang dimuliakan agar terdengar sah. Ini sama buruknya untuk semua alasan yang sama.
R .. GitHub BERHENTI MEMBANTU ICE
@ GavinMiller Mengatakan tidak apa-apa jika Anda menggunakan simpleton ... ooops, eufemisme singleton?
Juan Mendes
14

Masalahnya kurang bahwa mereka buruk , dan lebih banyak lagi mereka berbahaya . Mereka memiliki serangkaian pro dan kontra, dan ada situasi di mana mereka bisa menjadi yang paling efisien atau satu-satunya cara untuk mencapai tugas tertentu. Namun, mereka sangat mudah disalahgunakan, bahkan jika Anda mengambil langkah untuk selalu menggunakannya dengan benar.

Beberapa kelebihan:

  • Dapat diakses dari fungsi apa pun.
  • Dapat diakses dari berbagai utas.
  • Tidak akan pernah keluar dari ruang lingkup sampai program berakhir.

Beberapa kontra:

  • Dapat diakses dari fungsi apa pun, tanpa perlu diseret secara eksplisit sebagai parameter dan / atau didokumentasikan.
  • Tidak aman untuk benang.
  • Mencemari namespace global dan berpotensi menyebabkan tabrakan nama, kecuali tindakan diambil untuk mencegah hal ini.

Perhatikan, jika Anda mau, bahwa dua pro pertama dan dua kontra pertama yang saya daftarkan adalah hal yang sama persis, hanya dengan kata-kata yang berbeda. Ini karena fitur-fitur variabel global memang bisa berguna, tetapi fitur-fitur yang membuat mereka berguna adalah sumber dari semua masalah mereka.

Beberapa solusi potensial untuk beberapa masalah:

  • Pertimbangkan apakah mereka sebenarnya solusi terbaik atau paling efisien untuk masalah tersebut. Jika ada setiap solusi yang lebih baik, menggunakannya.
  • Tempatkan mereka di namespace [C ++] atau singleton struct [C, C ++] dengan nama yang unik (contoh yang bagus adalah Globalsatau GlobalVars), atau gunakan konvensi penamaan standar untuk variabel global (seperti global_[name]atau g_module_varNameStyle(seperti yang disebutkan oleh underscore_d dalam komentar )). Ini akan mendokumentasikan penggunaannya (Anda dapat menemukan kode yang menggunakan variabel global dengan mencari namespace / nama struct), dan meminimalkan dampak pada namespace global.
  • Untuk setiap fungsi yang mengakses variabel global, secara eksplisit mendokumentasikan variabel mana yang dibaca dan yang ditulisnya. Ini akan membuat pemecahan masalah lebih mudah.
  • Tempatkan mereka di file sumber mereka sendiri dan deklarasikan externdi header yang terkait, sehingga penggunaannya dapat dibatasi untuk unit kompilasi yang perlu mengaksesnya. Jika kode Anda bergantung pada banyak variabel global, tetapi setiap unit kompilasi hanya membutuhkan akses ke beberapa variabel, Anda dapat mempertimbangkan untuk mengurutkannya menjadi beberapa file sumber, jadi lebih mudah membatasi akses setiap file ke variabel global.
  • Mengatur mekanisme untuk mengunci dan membuka kuncinya, dan / atau merancang kode Anda sehingga sesedikit mungkin fungsi perlu benar-benar memodifikasi variabel global. Membaca mereka jauh lebih aman daripada menulisnya, meskipun balapan thread mungkin masih menimbulkan masalah dalam program multithreaded.
  • Pada dasarnya, minimalkan akses ke mereka, dan maksimalkan keunikan nama. Anda ingin menghindari tabrakan nama dan memiliki fungsi sesedikit mungkin yang berpotensi mengubah variabel apa pun yang diberikan.

Apakah mereka baik atau buruk tergantung pada bagaimana Anda menggunakannya. Mayoritas cenderung menggunakannya dengan buruk, karena itu kewaspadaan umum terhadap mereka. Jika digunakan dengan benar, mereka bisa menjadi keuntungan besar; Namun, jika digunakan dengan buruk, mereka dapat dan akan kembali menggigit Anda kapan dan bagaimana Anda tidak mengharapkannya.

Cara yang baik untuk melihatnya adalah bahwa mereka sendiri tidak buruk, tetapi mereka memungkinkan desain yang buruk, dan dapat melipatgandakan efek dari desain yang buruk secara eksponensial.


Sekalipun Anda tidak bermaksud menggunakannya, lebih baik mengetahui cara menggunakannya dengan aman dan memilih untuk tidak menggunakannya daripada tidak menggunakannya karena Anda tidak tahu cara menggunakannya dengan aman. Jika Anda pernah menemukan diri Anda dalam situasi di mana Anda perlu mempertahankan kode yang sudah ada sebelumnya yang bergantung pada variabel global, Anda mungkin berada dalam kesulitan jika Anda tidak tahu bagaimana menggunakannya dengan benar.

Justin Time - Pasang kembali Monica
sumber
1
+1 untuk pragmatisme. Seorang singleton sering hanya menambahkan pelat untuk membuat instance & refactor menjadi anggota, & Anda berakhir dengan ... variabel global, hanya menyamar dengan nama yang berbeda. Kenapa repot-repot, selain untuk menghindari Dosa Dunia pada teknis semata? Namespaces bagus sebagai penghalang, tetapi saya menemukan sederhana yang g_module_varNameStyledapat dibaca dengan sempurna. Untuk lebih jelasnya, saya tidak menggunakan global jika saya dapat menghindarinya dengan mudah - kata kunci dengan mudah , karena sejak saya berhenti percaya mereka harus dihindari - atau lebih tepatnya dikaburkan - bagaimanapun caranya, saya memiliki waktu yang jauh lebih baik, & saya kode (kejutan!) jauh lebih rapi
underscore_d
@underscore_d Ini terutama hanya untuk memiliki cara untuk membedakan antara variabel global dan lokal lebih mudah, dan juga untuk membuatnya lebih mudah untuk menemukan variabel global saat mencari kode Anda, dengan maksud untuk mencegah kebingungan apakah suatu variabel global atau lokal / parameter / anggota / dll. Konvensi penamaan standar seperti milik Anda juga berfungsi, asalkan konsisten. Mengedit jawaban saya dengan ide konvensi penamaan standar, terima kasih.
Waktu Justin - Kembalikan Monica
1
"Untuk fungsi apa pun ... secara eksplisit mendokumentasikan variabel mana" - ingat ini adalah hubungan transitif. Jika fungsi A memanggil fungsi B dan C, maka ia membaca dan menulis variabel yang ditulis oleh keduanya (ditambah yang langsung di tubuh itu)
Caleth
11

Seperti kata seseorang (saya parafrase) di utas lain "Aturan seperti ini tidak boleh dilanggar, sampai Anda sepenuhnya memahami konsekuensi dari melakukannya."

Ada saat-saat ketika variabel global diperlukan, atau setidaknya sangat membantu (Bekerja dengan panggilan balik sistem misalnya). Di sisi lain, mereka juga sangat berbahaya karena semua alasan Anda diberitahu.

Ada banyak aspek pemrograman yang mungkin harus diserahkan kepada para ahli. Terkadang Anda MEMBUTUHKAN pisau yang sangat tajam. Tapi Anda tidak bisa menggunakannya sampai Anda siap ...

Brian Postow
sumber
1
Saya setuju, jika Anda memahami konsekuensinya, tidak apa-apa melanggar aturan, tetapi jika Anda mendapati diri Anda sering melakukannya, Anda melakukan sesuatu yang salah
Juan Mendes
9

Variabel global umumnya buruk, terutama jika orang lain bekerja pada kode yang sama dan tidak ingin menghabiskan 20 menit mencari semua tempat variabel dirujuk. Dan menambahkan utas yang memodifikasi variabel membawa tingkat baru sakit kepala.

Konstanta global dalam ruang nama anonim yang digunakan dalam satu unit terjemahan baik-baik saja dan ada di mana-mana di aplikasi dan perpustakaan profesional. Tetapi jika data dapat diubah, dan / atau harus dibagi antara beberapa TU, Anda mungkin ingin merangkumnya - jika bukan karena desain, maka demi siapa pun yang men-debug atau bekerja dengan kode Anda.

Michel
sumber
9

Menggunakan variabel global adalah jenis seperti menyapu kotoran di bawah karpet. Ini adalah perbaikan cepat, dan jauh lebih mudah dalam jangka pendek daripada mendapatkan pengki atau penyedot debu untuk membersihkannya. Namun, jika Anda akhirnya memindahkan permadani nanti, Anda akan memiliki kejutan kejutan besar di bawahnya.

gnovice
sumber
metafora malas tanpa konteks! = answer
underscore_d
1
@underscore_d: Saya tidak setuju. Ini adalah pertanyaan diskusi, meskipun tidak ditandai seperti itu (mungkin karena usianya), dan jawaban seperti ini benar-benar valid, dan itu membuat titik yang menjawab pertanyaan OP.
gariepy
7

Variabel global buruk, jika memungkinkan Anda untuk memanipulasi aspek program yang hanya boleh dimodifikasi secara lokal. Dalam OOP global sering bertentangan dengan ide enkapsulasi.

Leonidas
sumber
7

Saya pikir profesor Anda mencoba menghentikan kebiasaan buruk bahkan sebelum itu dimulai.

Variabel global memiliki tempat mereka sendiri dan seperti banyak orang mengatakan mengetahui di mana dan kapan menggunakannya bisa rumit. Jadi saya pikir daripada masuk ke seluk-beluk mengapa, bagaimana, kapan, dan di mana variabel global profesor Anda memutuskan untuk hanya melarang. Siapa tahu, dia mungkin akan mencekal mereka di masa depan.

bong
sumber
7

Benar-benar tidak. Menyalahgunakan mereka ... itu buruk.

Melepaskan mereka tanpa berpikir demi itu hanya ... tanpa berpikir. Kecuali Anda mengetahui keuntungan dan kerugiannya, yang terbaik adalah menjauhi dan melakukan apa yang telah Anda pelajari / pelajari, tetapi secara implisit tidak ada yang salah dengan variabel global. Ketika Anda memahami pro dan kontra lebih baik membuat keputusan sendiri.

jheriko
sumber
3
-1 Ada banyak alasan untuk berhati-hati terhadap variabel global: yang terbesar bagi saya adalah bahwa dependensi tersembunyi dan global membuat kode pengujian dengan cara apa pun yang dapat diprediksi menjadi sangat sulit. Kecuali jika Anda tidak menghargai kemampuan untuk menguji kode Anda dengan cara otomatis, saya akan menyarankan bahwa variabel global tidak akan menyebabkan Anda kesusahan. Dan selain itu, dalam program yang terstruktur dengan baik selalu ada alternatif.
jkp
1
apa yang Anda katakan adalah overgeneralisasi besar-besaran, penggunaan negara global secara hati-hati tidak mencegah pengujian otomatis - pada kenyataannya hampir semua aplikasi memiliki keadaan global, apakah itu dibungkus secara dinamis sebagai contoh objek yang dienkapsulasi dengan baik atau data statis yang benar-benar mengeksposnya. tidak ada bedanya secara konseptual, masih ada dependensi - ini hanya tentang bagaimana mereka dikodekan.
jheriko
1
Persis. Mereka tidak terlalu "buruk" karena mereka "mudah pecah", pada dasarnya. Jika Anda tahu cara menggunakannya tanpa merusak apa pun, dan kapan menggunakannya alih-alih alternatif, itu bisa membantu. Kalau tidak ... tidak banyak.
Justin Time - Pasang kembali Monica
4

Variabel global baik-baik saja dalam program kecil, tetapi mengerikan jika digunakan dengan cara yang sama pada yang besar.

Ini berarti Anda dapat dengan mudah membiasakan menggunakannya saat belajar. Inilah yang profesor Anda coba lindungi dari Anda.

Ketika Anda lebih berpengalaman akan lebih mudah untuk belajar ketika mereka baik-baik saja.

Darron
sumber
4

Tidak, mereka tidak buruk sama sekali. Anda perlu melihat kode (mesin) yang dihasilkan oleh kompiler untuk membuat penentuan ini, kadang-kadang jauh lebih buruk untuk menggunakan lokal daripada global. Perhatikan juga bahwa menempatkan "statis" pada variabel lokal pada dasarnya menjadikannya global (dan menciptakan masalah jelek lainnya yang akan dipecahkan oleh global nyata). "global lokal" sangat buruk.

Global memberi Anda kontrol bersih atas penggunaan memori Anda juga, sesuatu yang jauh lebih sulit dilakukan dengan penduduk setempat. Hari-hari ini yang hanya penting di lingkungan tertanam di mana memori sangat terbatas. Sesuatu yang perlu diketahui sebelum Anda menganggap bahwa embedded adalah sama dengan lingkungan lain dan menganggap aturan pemrograman sama di seluruh papan.

Adalah baik bahwa Anda mempertanyakan aturan yang diajarkan, kebanyakan dari mereka bukan karena alasan Anda diberitahu. Namun, pelajaran yang paling penting bukanlah bahwa ini adalah peraturan yang harus Anda bawa selamanya, tetapi ini adalah aturan yang harus dihormati untuk lulus dari kelas ini dan bergerak maju. Dalam hidup Anda akan menemukan bahwa untuk perusahaan XYZ Anda akan memiliki aturan pemrograman lain yang pada akhirnya harus Anda hormati agar tetap mendapatkan gaji. Dalam kedua situasi itu Anda bisa memperdebatkan aturan itu, tetapi saya pikir Anda akan memiliki keberuntungan yang jauh lebih baik di pekerjaan daripada di sekolah. Anda hanyalah salah satu dari banyak siswa, kursi Anda akan segera diganti, profesor tidak akan, pada pekerjaan Anda adalah salah satu dari tim kecil pemain yang harus melihat produk ini sampai akhir dan dalam lingkungan yang dikembangkan aturan untuk manfaat dari anggota tim serta produk dan perusahaan, jadi jika semua orang berpikiran sama atau jika untuk produk tertentu ada alasan teknis yang baik untuk melanggar sesuatu yang Anda pelajari di perguruan tinggi atau buku tentang pemrograman generik, kemudian jual ide Anda kepada tim dan tuliskan sebagai metode yang valid jika bukan yang disukai . Semuanya adalah permainan yang adil di dunia nyata.

Jika Anda mengikuti semua aturan pemrograman yang diajarkan kepada Anda di sekolah atau buku, karier pemrograman Anda akan sangat terbatas. Anda mungkin dapat bertahan hidup dan memiliki karier yang subur, tetapi luas dan lebar lingkungan yang tersedia bagi Anda akan sangat terbatas. Jika Anda tahu bagaimana dan mengapa aturan itu ada dan dapat mempertahankannya, itu bagus, jika Anda satu-satunya alasan adalah "karena guru saya berkata begitu", well itu tidak begitu baik.

Perhatikan bahwa topik seperti ini sering diperdebatkan di tempat kerja dan akan terus berlanjut, karena penyusun dan pemroses (dan bahasa) berevolusi demikian juga aturan-aturan semacam ini dan tanpa mempertahankan posisi Anda dan mungkin diajarkan pelajaran oleh seseorang dengan pendapat lain yang tidak Anda sukai maju kedepan.

Sementara itu, maka lakukan saja apa yang dikatakan paling keras atau yang membawa tongkat terbesar berkata (sampai Anda yang berteriak paling keras dan membawa tongkat terbesar).

old_timer
sumber
4
Apakah ini hanya cara lain untuk mengatakan "tidak ada yang dipecat karena membeli IBM"?
Gordon Potter
1
Poin bagus bahwa untuk beberapa aplikasi menggunakan variabel global sebenarnya dapat membuat pekerjaan lebih mudah. Secara umum menggunakan variabel global adalah sumber masalah dengan jalur tersembunyi kopling antara bagian sumber. Namun memiliki area memori bersama yang dirujuk sebagai global digunakan untuk sejumlah implementasi seperti antarmuka perangkat atau mungkin tabel parameter global yang berisi konstanta dari berbagai jenis atau tabel lompatan.
Richard Chambers
4

Saya ingin berdebat menentang poin yang dibuat di seluruh utas ini yang membuat multi-threading lebih sulit atau tidak mungkin dilakukan. Variabel global adalah keadaan bersama, tetapi alternatif untuk global (misal lewat pointer di sekitar) mungkin juga berbagi keadaan. Masalah dengan multi-threading adalah bagaimana cara menggunakan keadaan bersama dengan benar, bukan apakah keadaan itu terjadi bersama melalui variabel global atau sesuatu yang lain.

Sebagian besar saat Anda melakukan multi-threading, Anda perlu membagikan sesuatu. Dalam pola produsen-konsumen misalnya, Anda mungkin berbagi antrean aman yang berisi unit kerja. Dan Anda diizinkan untuk membagikannya karena struktur data itu aman digunakan. Apakah antrian itu bersifat global atau tidak, sama sekali tidak relevan ketika menyangkut keamanan utas.

Harapan tersirat yang dinyatakan dalam utas ini bahwa mengubah program dari satu-utas menjadi multi-utas akan lebih mudah bila tidak menggunakan global adalah naif. Ya, global membuat Anda lebih mudah menembak diri sendiri, tetapi ada banyak cara untuk menembak diri sendiri.

Saya tidak menganjurkan global, karena poin lainnya masih berdiri, poin saya hanyalah bahwa jumlah utas dalam suatu program tidak ada hubungannya dengan ruang lingkup variabel.

Andreas Haferburg
sumber
3

Ya, karena jika Anda membiarkan programmer yang tidak kompeten menggunakannya (baca 90% terutama ilmuwan), Anda akan mendapatkan lebih dari 600 variabel global yang tersebar di lebih dari 20 file dan proyek 12.000 baris di mana 80% dari fungsi tidak berlaku, kembali kosong, dan beroperasi sepenuhnya pada negara global.

Dengan cepat menjadi tidak mungkin untuk memahami apa yang sedang terjadi pada satu titik kecuali Anda tahu seluruh proyek.

Wezzman
sumber
2

Penggunaan variabel Global sebenarnya tergantung pada persyaratan. Keuntungannya adalah, ini mengurangi overhead melewati nilai-nilai berulang kali.

Tetapi profesor Anda benar karena menimbulkan masalah keamanan sehingga penggunaan variabel global harus dihindari sebanyak mungkin. Variabel global juga menciptakan masalah yang terkadang sulit untuk di-debug .

Sebagai contoh:-

Situasi ketika nilai-nilai variabel semakin dimodifikasi pada saat runtime . Pada saat itu sulit untuk mengidentifikasi bagian mana dari kode yang memodifikasi dan pada kondisi apa.

Mufaddal Kagda
sumber
2

Global bagus untuk konfigurasi . Ketika kami ingin konfigurasi / perubahan kami memiliki dampak global pada seluruh proyek .

Jadi kita dapat mengubah satu konfigurasi dan perubahan diarahkan ke seluruh proyek . Tapi saya harus memperingatkan Anda harus sangat pintar untuk menggunakan global.

Maaz Rehman
sumber
1

Cepat atau lambat Anda akan perlu mengubah cara variabel itu diatur atau apa yang terjadi ketika diakses, atau Anda hanya perlu mencari di mana itu diubah.

Secara praktis selalu lebih baik untuk tidak memiliki variabel global. Cukup tulis bendungan dapatkan dan atur metode, dan jadilah kelenjar saat Anda membutuhkannya sehari, seminggu atau sebulan kemudian.

Bloodboiler
sumber
1

Saya biasanya menggunakan global untuk nilai-nilai yang jarang berubah seperti lajang atau fungsi pointer ke fungsi di perpustakaan yang dimuat secara dinamis. Menggunakan global yang bisa berubah dalam aplikasi multithreaded cenderung mengarah ke sulit untuk melacak bug jadi saya mencoba untuk menghindari ini sebagai aturan umum.

Menggunakan global alih-alih menyampaikan argumen seringkali lebih cepat, tetapi jika Anda menulis aplikasi multithreaded, yang sering Anda lakukan saat ini, umumnya tidak berfungsi dengan baik (Anda dapat menggunakan thread-statika tetapi kemudian peningkatan kinerja dipertanyakan) .

Erik Ohlsson
sumber
1

Dalam aplikasi web dalam suatu perusahaan, dapat digunakan untuk menyimpan data khusus sesi / jendela / utas / pengguna di server untuk alasan pengoptimalan dan menjaga agar tidak kehilangan pekerjaan di mana koneksi tidak stabil. Seperti disebutkan, kondisi lomba perlu ditangani. Kami menggunakan satu instance kelas untuk informasi ini dan dikelola dengan hati-hati.

xxyzzy
sumber
1

Pada akhirnya, program atau aplikasi Anda masih bisa berfungsi tetapi ini soal rapi dan memiliki pemahaman yang lengkap tentang apa yang terjadi. Jika Anda berbagi nilai variabel di antara semua fungsi, mungkin menjadi sulit untuk melacak fungsi apa yang mengubah nilai (jika fungsi melakukannya) dan membuat proses debug sejuta kali lebih sulit

alaboudi
sumber
0

keamanan kurang berarti setiap orang dapat memanipulasi variabel jika mereka dinyatakan global, untuk yang ini menjelaskan ambil contoh ini jika Anda memiliki saldo sebagai variabel global dalam program bank Anda fungsi pengguna dapat memanipulasi ini serta petugas bank juga dapat memanipulasi ini jadi ada masalah. hanya pengguna harus diberikan fungsi read only dan withdraw tetapi petugas bank dapat menambahkan jumlah ketika pengguna secara pribadi memberikan uang tunai di meja. ini adalah cara kerjanya

Vamsi Pavan Mahesh
sumber
-1

Dalam aplikasi multi-utas, gunakan variabel lokal sebagai pengganti variabel global untuk menghindari kondisi balapan.

Kondisi ras terjadi ketika beberapa utas mengakses sumber daya bersama, dengan setidaknya satu utas memiliki akses tulis ke data. Kemudian, hasil dari program tidak dapat diprediksi, dan tergantung pada urutan akses ke data dengan utas yang berbeda.

Lebih lanjut tentang ini di sini, https://software.intel.com/en-us/articles/use-intel-parallel-inspector-to-find-race-conditions-in-openmp-based-multithreaded-code

Kiriloff
sumber
Untuk anak cucu: ini sebagian benar di terbaik. "Variabel lokal" dalam jawaban ini merujuk pada variabel thread- lokal, bukan variabel lokal-lingkup yang lebih umum yang dirujuk OP. Efek samping dari memodifikasi variabel global dengan cara yang tidak aman sangat berbeda dengan yang mengubah keadaan global dengan cara yang tidak bersamaan.
Jules