Saya punya perpustakaan yang saya buat,
mylib.c:
#include <mylib.h>
int
testlib() {
printf("Hello world\n");
return (0);
}
mylib.h:
#include <stdio.h>
extern int testlib();
Dalam program saya, saya mencoba memanggil fungsi pustaka ini:
myprogram.c:
#include <mylib.h>
int
main (int argc, char *argv[]) {
testlib();
return (0);
}
Ketika saya mencoba untuk mengkompilasi program ini, saya mendapatkan kesalahan berikut:
Dalam file termasuk dari myprogram.c: 1 mylib.h: 2 peringatan: deklarasi fungsi bukan prototipe
Saya menggunakan: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
Pertanyaan saya adalah, apa cara yang tepat untuk mendeklarasikan prototipe fungsi?
Jawaban:
Dalam C
int foo()
danint foo(void)
berbagai fungsi.int foo()
menerima sejumlah argumen sembarang, sementaraint foo(void)
menerima 0 argumen. Dalam C ++ artinya sama. Saya menyarankan agar Anda menggunakanvoid
secara konsisten ketika Anda bermaksud tidak ada argumen.Jika Anda memiliki variabel
a
,extern int a;
adalah cara untuk memberi tahu kompiler bahwa itua
adalah simbol yang mungkin ada di unit terjemahan yang berbeda (C kompiler berbicara untuk file sumber), jangan menyelesaikannya sampai waktu tautan. Di sisi lain, simbol yang merupakan nama fungsi diselesaikan pada saat tautan. Arti penentu kelas penyimpanan pada fungsi (extern
,static
) hanya memengaruhi visibilitasnya danextern
merupakan default, jadiextern
sebenarnya tidak perlu.Saya sarankan menghapus
extern
, itu asing dan biasanya dihilangkan.sumber
(void)
dalam C untuk menunjukkan bahwa suatu fungsi tidak membutuhkan argumen. Di C ++, kecuali Anda secara spesifik membutuhkan kode Anda untuk mengkompilasi sebagai C dan sebagai C ++, cukup gunakan()
.Jawaban cepat: ubah
int testlib()
keint testlib(void)
untuk menentukan bahwa fungsi tidak memerlukan argumen.Sebuah prototipe adalah dengan definisi sebuah deklarasi fungsi yang menentukan jenis (s) dari argumen fungsi (s).
Deklarasi fungsi non-prototipe seperti
adalah deklarasi gaya lama yang tidak menentukan jumlah atau tipe argumen. (Sebelum standar ANSI C 1989, ini adalah satu-satunya jenis deklarasi fungsi yang tersedia dalam bahasa tersebut.) Anda dapat memanggil fungsi semacam itu dengan sejumlah argumen arbitrer, dan kompilator tidak diharuskan mengeluh - tetapi jika panggilan tidak konsisten dengan definisi , program Anda memiliki perilaku yang tidak ditentukan.
Untuk fungsi yang mengambil satu atau lebih argumen, Anda bisa menentukan tipe setiap argumen dalam deklarasi:
Fungsi tanpa argumen adalah kasus khusus. Secara logis, tanda kurung kosong akan menjadi cara yang baik untuk menentukan argumen itu tetapi sintaks sudah digunakan untuk deklarasi fungsi gaya lama, sehingga komite ANSI C menemukan sintaks baru menggunakan
void
kata kunci:Definisi fungsi (yang mencakup kode untuk apa fungsi sebenarnya) juga menyediakan deklarasi . Dalam kasus Anda, Anda memiliki sesuatu yang mirip dengan:
Ini memberikan deklarasi non-prototipe untuk
testlib
. Sebagai definisi, ini memberitahu kompiler yangtestlib
tidak memiliki parameter, tetapi sebagai deklarasi, itu hanya memberitahu kompiler yangtestlib
mengambil beberapa nomor dan jenis argumen yang tidak ditentukan tetapi tetap.Jika Anda mengubah
()
ke(void)
deklarasi menjadi prototipe.Keuntungan dari prototipe adalah bahwa jika Anda secara tidak sengaja memanggil
testlib
dengan satu atau lebih argumen, kompiler akan mendiagnosis kesalahan tersebut.(C ++ memiliki aturan yang sedikit berbeda. C ++ tidak memiliki deklarasi fungsi gaya lama, dan tanda kurung kosong secara khusus berarti bahwa suatu fungsi tidak memerlukan argumen. C ++ mendukung
(void)
sintaks untuk konsistensi dengan C. Tetapi kecuali Anda secara spesifik memerlukan kode Anda untuk mengkompilasi keduanya sebagai C dan sebagai C ++, Anda mungkin harus menggunakan()
dalam C ++ dan(void)
sintaks dalam C.)sumber
Mencoba:
sumber