Pertanyaan saya adalah kapan fungsi harus direferensikan dengan extern
kata kunci dalam C.
Saya gagal melihat kapan ini harus digunakan dalam praktek. Saat saya menulis sebuah program, semua fungsi yang saya gunakan tersedia melalui file header yang saya sertakan. Jadi mengapa bermanfaat untuk extern
mendapatkan akses ke sesuatu yang tidak terpapar dalam file header?
Saya mungkin berpikir tentang cara extern
kerjanya yang salah, dan jika demikian tolong perbaiki saya.
Sunting: Haruskah Anda melakukan extern
sesuatu ketika itu adalah deklarasi default tanpa kata kunci dalam file header?
Jawaban:
"
extern
" mengubah tautannya. Dengan kata kunci, fungsi / variabel diasumsikan tersedia di tempat lain dan penyelesaiannya ditunda ke tautan.Ada perbedaan antara "extern" pada fungsi dan pada variabel: pada variabel itu tidak instantiate variabel itu sendiri, yaitu tidak mengalokasikan memori apa pun. Ini perlu dilakukan di tempat lain. Karenanya, penting jika Anda ingin mengimpor variabel dari tempat lain. Untuk fungsi, ini hanya memberi tahu kompiler bahwa hubungan adalah eksternal. Karena ini adalah default (Anda menggunakan kata kunci "statis" untuk menunjukkan bahwa suatu fungsi tidak terikat menggunakan hubungan eksternal) Anda tidak perlu menggunakannya secara eksplisit.
sumber
extern memberi tahu kompiler bahwa data ini didefinisikan di suatu tempat dan akan terhubung dengan tautan.
Dengan bantuan tanggapan di sini dan berbicara dengan beberapa teman di sini adalah contoh praktis dari penggunaan eksternal .
Contoh 1 - untuk menunjukkan perangkap:
Jika myCFile1.o dan myCFile2.o ditautkan, masing-masing file c memiliki salinan errno yang terpisah . Ini adalah masalah karena errno yang sama seharusnya tersedia di semua file yang ditautkan.
Contoh 2 - Perbaikan.
Sekarang jika myCFile1.o dan MyCFile2.o keduanya ditautkan oleh linker, keduanya akan menunjuk ke errno yang sama . Dengan demikian, penyelesaian implementasinya dengan eksternal .
sumber
-Wall
dan-pedantic
. Mengapa dan bagaimana ?Telah dinyatakan bahwa
extern
kata kunci berlebihan untuk fungsi.Adapun variabel yang dibagikan di seluruh unit kompilasi, Anda harus mendeklarasikannya dalam file header dengan kata kunci extern, lalu mendefinisikannya dalam file sumber tunggal, tanpa kata kunci extern. File sumber tunggal harus yang berbagi nama file header, untuk praktik terbaik.
sumber
Bertahun-tahun kemudian, saya menemukan pertanyaan ini. Setelah membaca setiap jawaban dan komentar, saya pikir saya bisa mengklarifikasi beberapa detail ... Ini bisa berguna bagi orang-orang yang datang ke sini melalui pencarian Google.
Pertanyaannya secara khusus tentang penggunaan fungsi "eksternal", jadi saya akan mengabaikan penggunaan "eksternal" dengan variabel global.
Mari kita tentukan 3 prototipe fungsi:
File header dapat digunakan oleh kode sumber utama sebagai berikut:
Untuk mengkompilasi dan menautkan, kita harus mendefinisikan "function_2" dalam file kode sumber yang sama tempat kita memanggil fungsi itu. Dua fungsi lainnya dapat didefinisikan dalam kode sumber yang berbeda " .C" atau mereka dapat ditemukan di file biner apa pun ( .OBJ, * .LIB, * .DLL), yang mungkin tidak memiliki kode sumbernya.
Mari kita sertakan lagi header "my_project.H" dalam file "* .C" yang berbeda untuk lebih memahami perbedaannya. Dalam proyek yang sama, kami menambahkan file berikut:
Fitur penting untuk diperhatikan:
Ketika suatu fungsi didefinisikan sebagai "statis" dalam file header, kompiler / linker harus menemukan contoh fungsi dengan nama itu di setiap modul yang menggunakan file yang menyertakan itu.
Fungsi yang merupakan bagian dari pustaka C dapat diganti hanya dalam satu modul dengan mendefinisikan ulang prototipe dengan "statis" hanya dalam modul itu. Misalnya, ganti panggilan apa pun ke "malloc" dan "gratis" untuk menambahkan fitur deteksi kebocoran memori.
Specifier "extern" sebenarnya tidak diperlukan untuk fungsi. Ketika "statis" tidak ditemukan, suatu fungsi selalu dianggap "eksternal".
Namun, "extern" bukan default untuk variabel. Biasanya, setiap file header yang mendefinisikan variabel agar terlihat di banyak modul perlu menggunakan "extern". Satu-satunya pengecualian adalah jika file header dijamin akan disertakan dari satu dan hanya satu modul.
Banyak manajer proyek kemudian mengharuskan variabel tersebut ditempatkan di awal modul, bukan di dalam file header apa pun. Beberapa proyek besar, seperti emulator permainan video "Mame" bahkan mengharuskan variabel tersebut hanya muncul di atas fungsi pertama yang menggunakannya.
sumber
Dalam C, 'extern' tersirat untuk prototipe fungsi, seperti prototipe menyatakan fungsi yang didefinisikan di tempat lain. Dengan kata lain, prototipe fungsi memiliki hubungan eksternal secara default; menggunakan 'extern' baik-baik saja, tetapi berlebihan.
(Jika diperlukan tautan statis, fungsi tersebut harus dinyatakan sebagai 'statis' baik dalam prototipe maupun header fungsinya, dan ini biasanya harus keduanya dalam file .c yang sama).
sumber
Artikel yang sangat bagus yang saya sampaikan tentang
extern
kata kunci, bersama dengan contoh-contohnya: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/Meskipun saya tidak setuju bahwa menggunakan
extern
deklarasi fungsi adalah berlebihan. Ini seharusnya menjadi pengaturan kompiler. Jadi saya sarankan menggunakanextern
deklarasi fungsi pada saat dibutuhkan.sumber
Jika setiap file dalam program Anda pertama kali dikompilasi ke file objek, maka file objek dihubungkan bersama, Anda perlu
extern
. Ini memberitahu kompiler "Fungsi ini ada, tetapi kode untuk itu ada di tempat lain. Jangan panik."sumber
Seharusnya semua deklarasi fungsi dan variabel dalam file header
extern
.Pengecualian untuk aturan ini adalah fungsi sebaris yang didefinisikan di header dan variabel yang - walaupun didefinisikan dalam header - harus bersifat lokal ke unit terjemahan (file sumber yang dimasukkan header): ini seharusnya
static
.Dalam file sumber,
extern
tidak boleh digunakan untuk fungsi dan variabel yang ditentukan dalam file. Awali definisi lokal denganstatic
dan tidak melakukan apa pun untuk definisi bersama - mereka akan menjadi simbol eksternal secara default.Satu-satunya alasan untuk menggunakan
extern
sama sekali dalam file sumber adalah untuk menyatakan fungsi dan variabel yang didefinisikan dalam file sumber lain dan yang tidak ada file header disediakan.Mendeklarasikan prototipe fungsi
extern
sebenarnya tidak perlu. Beberapa orang tidak menyukainya karena itu hanya akan membuang-buang ruang dan fungsi deklarasi sudah memiliki kecenderungan untuk meluap batas garis. Orang lain menyukainya karena cara ini, fungsi dan variabel dapat diperlakukan dengan cara yang sama.sumber
extern
adalah opsional untuk deklarasi fungsi, tapi saya suka memperlakukan variabel dan fungsi dengan cara yang sama - setidaknya itu hal yang paling masuk akal yang bisa saya buat, karena saya tidak ingat persis mengapa saya mulai melakukan ini;)Fungsi yang sebenarnya didefinisikan dalam file sumber lain hanya boleh dideklarasikan dalam header. Dalam hal ini, Anda harus menggunakan eksternal ketika mendeklarasikan prototipe di header.
Sebagian besar waktu, fungsi Anda akan menjadi salah satu dari yang berikut (lebih seperti praktik terbaik):
sumber
Ketika Anda memiliki fungsi yang didefinisikan pada dll atau lib yang berbeda, sehingga kompiler mencari linker untuk menemukannya. Kasus khas adalah ketika Anda memanggil fungsi dari OS OS.
sumber