Mam utworzoną przeze mnie bibliotekę,
mylib.c:
#include <mylib.h>
int
testlib() {
printf("Hello world\n");
return (0);
}
mylib.h:
#include <stdio.h>
extern int testlib();
W moim programie próbowałem wywołać tę funkcję biblioteczną:
myprogram.c:
#include <mylib.h>
int
main (int argc, char *argv[]) {
testlib();
return (0);
}
Kiedy próbuję skompilować ten program, pojawia się następujący błąd:
W pliku zawartym z myprogram.c: 1 mylib.h: 2 ostrzeżenie: deklaracja funkcji nie jest prototypem
Używam: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
Moje pytanie brzmi: jaki jest właściwy sposób zadeklarowania prototypu funkcji?
Odpowiedzi:
W C
int foo()
iint foo(void)
są różne funkcje.int foo()
akceptuje dowolną liczbę argumentów, aint foo(void)
akceptuje 0 argumentów. W C ++ mają na myśli to samo. Sugeruję, abyś używałvoid
konsekwentnie, gdy nie masz na myśli żadnych argumentów.Jeśli masz zmienną
a
,extern int a;
jest to sposób, aby powiedzieć kompilatorowi, żea
jest to symbol, który może być obecny w innej jednostce tłumaczenia (kompilator C mówi o pliku źródłowym), nie rozwiązuj go do czasu połączenia. Z drugiej strony symbole, które są nazwami funkcji, są i tak rozwiązywane w czasie łączenia. Znaczenie specyfikatora klasy pamięci w funkcji (extern
,static
) wpływa tylko na jej widoczność iextern
jest wartością domyślną, więc wextern
rzeczywistości jest niepotrzebne.Sugeruję usunięcie
extern
, jest to obce i zwykle jest pomijane.źródło
(void)
w C, aby wskazać, że funkcja nie przyjmuje argumentów. W C ++, chyba że potrzebujesz kodu do kompilacji zarówno jako C, jak i C ++, po prostu użyj()
.Szybka odpowiedź: zmień
int testlib()
na,int testlib(void)
aby określić, że funkcja nie przyjmuje argumentów.Prototyp jest z definicji deklaracja funkcja, która określa typ (y) argumentów danej funkcji (S).
Nie-prototypowa deklaracja funkcji, taka jak
jest deklaracją w starym stylu, która nie określa liczby ani typów argumentów. (Przed standardem ANSI C z 1989 r. Był to jedyny rodzaj deklaracji funkcji dostępny w tym języku). Możesz wywołać taką funkcję z dowolną liczbą argumentów, a kompilator nie musi narzekać - ale jeśli call jest niezgodne z definicją , Twój program ma niezdefiniowane zachowanie.
W przypadku funkcji, która przyjmuje jeden lub więcej argumentów, możesz określić typ każdego argumentu w deklaracji:
Funkcje bez argumentów są przypadkiem specjalnym. Logicznie rzecz biorąc, puste nawiasy byłyby dobrym sposobem określenia tego argumentu, ale ta składnia była już używana w deklaracjach funkcji w starym stylu, więc komitet ANSI C wymyślił nową składnię za pomocą
void
słowa kluczowego:Definicja funkcji (która zawiera kod określający, co funkcja faktycznie robi) również zawiera deklarację . W twoim przypadku masz coś podobnego do:
Zapewnia to deklarację nie będącą prototypem
testlib
. Z definicji mówi to kompilatorowi, żetestlib
nie ma parametrów, ale jako deklaracja mówi kompilatorowi tylko, żetestlib
pobiera nieokreśloną, ale stałą liczbę i typ (y) argumentów.Po zmianie
()
do(void)
deklaracji staje się prototypem.Zaletą prototypu jest to, że jeśli przypadkowo wywołasz
testlib
jeden lub więcej argumentów, kompilator zdiagnozuje błąd.(C ++ ma nieco inne zasady. C ++ nie posiada deklaracje funkcji w starym stylu i pustych nawiasów konkretnie oznacza to, że funkcja przyjmuje żadnych argumentów. C ++ obsługuje
(void)
składni dla spójności z C. Ale chyba specjalnie potrzebny jest kod do kompilowania zarówno jako C i jako C ++ powinieneś prawdopodobnie użyć()
w C ++ i(void)
składni w C.)źródło
Próbować:
źródło