2009-11-23 7 views
8

Mam następujący kod C:Dlaczego gcc zgłasza "ukrytą deklarację funkcji" zaokrągloną "?

#include <math.h> 

int main(int argc, char ** argv) 
{ 
    double mydouble = 100.0; 
    double whatever = round(mydouble); 

    return (int) whatever; 
} 

Kiedy skompilować to, dostaję ostrzeżenia:

round_test.c: In function ‘main’: 
round_test.c:6: warning: implicit declaration of function ‘round’ 
round_test.c:6: warning: incompatible implicit declaration of built-in function ‘round’ 

jestem zardzewiały z C, ale myślałem, że #include przyniósł oświadczenie dla rundy() do zakresu. Sprawdziłem mój standard ANSI (C99 to jedyny egzemplarz, jaki mam), który potwierdza, że ​​funkcja round() istnieje w nagłówku math.h. Czego tu mi brakuje?

Edytuj: Kompilatorem jest GCC 4.3.2 na Ubuntu (nieustraszony, IIRC). Uruchamianie gcc -E daje:

$ gcc -E round_test.c | grep round 
# 1 "round_test.c" 
# 1 "round_test.c" 
# 2 "round_test.c" 2 
    double whatever = round(mydouble); 

, więc definicja oczywiście nie znajduje się w nagłówkach.

Odpowiedz

17

Widzę, że używasz gcc.

Domyślnie gcc używa standardu podobnego do C89. możesz „zmusić” go do używania standardu C99 (części spełnia on)

gcc -std=c99 -pedantic ... 

Cytat GCC Manual

Domyślnie GCC zapewnia pewne rozszerzeń do języka C, które na W rzadkich przypadkach konflikt ze standardem C . Zobacz Rozszerzenia do rodziny języków C . Użycie opcji -std wymienionych powyżej wyłączy tych rozszerzeń, w których będą one konfliktować ze standardową wersją C. Możesz także wybrać rozszerzoną wersję języka C w języku jawnie z -std = gnu89 (dla C89 z rozszerzeniami GNU ) lub -std = gnu99 (dla C99 z rozszerzeniami GNU). Domyślnie, jeśli bez opcji dialektu języka C są podane , to -std = gnu89; to zmieni na -std = gnu99 w jakimś przyszłym wydaniu po zakończeniu obsługi C99. Niektóre funkcje , które są częścią standardu C99 , są akceptowane jako rozszerzenia w trybieC89.

+1

Dzięki, -std = c99 wydawało się to rozwiązać. Nie zdawałem sobie sprawy, że runda() była dodatkiem C99 (i oczywiście wszystkie moje referencje to C99 i nie wspominając o tym) –

+0

(zaskoczony wygląd) Czy runda() naprawdę jest dodatkiem C99? –

+0

Dobrze, C89 nie opisywało funkcji 'round()' (oczywiście kompilatory mogą zapewnić ją jako rozszerzenie). – pmg

3

Coś musi być nie tak z instalacją gcc, nagłówkami systemu lub opcjami kompilacji.

Spróbuj skompilować za pomocą -E. To pokaże ci, jakie dane wyjściowe preprocesora - w tym, które nagłówki są uwzględniane i co w nich jest. W moim systemie Ubuntu Linux to około 1000 linii wyjściowych, w tym w ten sposób:

extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__)); 
+0

Jestem na Ubuntu 9.10 (Karmic). Tutaj '#include ' ładuje /usr/include/math.h który ładuje /usr/include/bits/mathcalls.h który zawiera deklarację. –

0

Kod wpiszesz kompiluje czysto na MacOS X 10.5.8 z GCC 4.0.1. Jeśli użyjesz opcji "-Wall-Wextra", to narzeka na niewykorzystane parametry argc i argv - nie istotne.

Czy obejrzałeś w swoim urządzeniu <math.h>?

Czy próbowałeś z opcjami takimi jak "-stc = c99"?

3

Trzeba powiedzieć gcc, który chcesz C99, i że chcesz połączyć w libm:

gcc -std=c99 -lm round_test.c 
-2

trzeba połączyć z biblioteki matematycznej. Dlatego podczas kompilacji należy dodać flagę -lm.

+1

Dzięki za wejście, ale jest to problem kompilacji, a nie link. Zdałem sobie sprawę z tego, że pominąłem komendę kompilatora (moje złe), ale kompilowałem z gcc -c. –

0

C99 było odpowiedzią, ale cała historia jest nieco bardziej skomplikowana. Powodem, dla którego bawiło mnie to było to, że próbowałem skompilować bibliotekę napisaną dla Windowsa, która miała własną "zoptymalizowaną" definicję round(). Pojawił się błąd łącznika informujący mnie, że definicja kolidowała z wbudowaną, więc usunąłem definicję (i deklarację). Kiedy już to zrobiłem, zacząłem otrzymywać "błąd ukrytej deklaracji".

Wygląda na to, że domyślny tryb kompilacji (bez flagi -std = c99) nie jest zgodny z C89 ani C99: jeśli był zgodny z C89, powinieneś być w stanie podać niestandardową definicję round() bez konfliktu, i jeśli było zgodne z C99, deklaracja powinna być w matematyce.

+1

Tryb domyślny to '-std = gnu89' :) – pmg