2011-02-04 10 views
16

Próbuję skompilować program C w systemie Linux. Mam oświadczenie #include dla .Czy opcja -std = c99 uniemożliwi prawidłowe działanie #includes?

Kiedy skompilować program z gcc następująco:

gcc -std=c99 -g -o progfoo progfoo.c progbar.c 

dostaję ostrzeżenia o Implicit declaration of function [srand48, drand48, bzero, or close].

Kompilacja zamiast jak:

gcc -g -o progfoo progfoo.c progbar.c 

nie daje mi ostrzeżenia, ale nie krzyczeć o moim stosowania for pętli (co było uzasadnienie do dodawania -std=c99 w pierwszej kolejności).

Wzmianki, w tym <stdlib.h>, które mam, nie jestem pewien, co jeszcze może być problemem. Pętle for nie są niezbędne do niczego (były tylko po to, aby zaoszczędzić czas podczas inicjalizacji tablicy), więc nie mam problemu z ich usunięciem, ale zanim to zrobię, chciałbym potwierdzić, czy standard c99 zastępuje jakiś aspekt mojego #include sprawozdania.

Używam gcc 4.1.2-50 (Red Hat).

Odpowiedz

12

Czy opcja -std = c99 uniemożliwi prawidłowe działanie #include?

Nie, ale mogą pojawić się ograniczenia w swojej wiedzy, w jaki sposób one działają :-)


Chociaż funkcje [sd]rand48 mają prototyp w stdlib.h, są one wewnątrz #ifdef, przynajmniej w moim systemie:

#if defined __USE_SVID || defined __USE_XOPEN 

Prawdopodobnie konieczne będzie jednoznaczne ustawienie jednego z tych makr.

Jednak zanim spróbujesz, należy pamiętać, że to nie działa. To dlatego, że wszystkie te rzeczy są kontrolowane przez gcc 's feature test macros.

Istnieje bardzo skomplikowany zestaw reguł używanych do włączania lub wyłączania określonych funkcji w features.h, a utworzone tam makra kontrolują, co zawierają pliki nagłówkowe i wykluczają je. Wersje __USE_* są usuwane i ustawiane w tym pliku nagłówkowym na podstawie innych makr dostarczonych przez ciebie.

Na przykład, aby uzyskać __USE_SVID zestaw, aby można było użyć srand48, należy dostarczyć kompilatorowi parametr -D_SVID_SOURCE.

Ale może prostszym sposobem jest użycie C99 z rozszerzeniami GNU. Aby to zrobić, zamień -std=c99 na -std=gnu99.

I, dlai close, można je uzyskać odpowiednio od strings.h i unistd.h.

byłem trochę zdezorientowany na początku, dlaczego te skompilowane z -std=c99 kiedy mają absolutnie nicdo czynienia z C99, ale potem zdałem sobie sprawę, że flaga kontroluje tylko to, co standardowe nagłówki C dać.

Ani strings.h (uwaga nazwy w liczbie mnogiej, to niestring.h) ani unistd.h są częścią ISO C

+2

+1, ale w rzeczywistości są to makra, a nie zmienne. –

+0

Dobra rzecz, @Matteo, mam na myśli _macros_ jako te, które _do_ rzeczy, jak '#define halfOf (x) ((x)/2)', w przeciwieństwie do "flag" do kontrolowania kompilacji. Ale masz rację, a użycie "zmiennej" pracy przeze mnie może doprowadzić do pomylenia z rzeczywistymi zmiennymi. Więc zmieniłem to zgodnie z twoją sugestią. – paxdiablo

+2

Dobrze. Pomocne może być stwierdzenie, że podczas kompilacji bez flagi '-std =', pytasz o '-std = gnu89', która jest C89 plus rozszerzenia GNU - więc odpowiednikiem C99 dla tego trybu jest' -std = gnu99 '. – caf

6

Wygląda na to, że funkcje, których używasz, nie są zgodne z ISO C99, więc gdy poprosisz o ścisłą zgodność z ustawą C99 na poziomie , nie będą one widoczne.

informacji tutaj: https://bugzilla.redhat.com/show_bug.cgi?id=130815

Flaga -D_POSIX_C_SOURCE=200809L powinno działać.

Zobacz też to pytanie: Why can't gcc find the random() interface when -std=c99 is set?

+2

Tak, jak mam zrobić prototyp funkcji dla "printf" w HelloWorld.c? Nie sądzę, żebyś rozumiał mój problem. –

+0

Otrzymuje ostrzeżenie o tym, że system zawiera pliki (stdlib.h), jeśli dobrze rozumiem, a nie w jego własnym kodzie. – Earlz

+0

Niestety, nie zdawałem sobie sprawy, że funkcje te nie zostały napisane samodzielnie, ponieważ piszę tylko kod C99 i nigdy z nich nie korzystałem. Zmieniono moją odpowiedź. – Kevin

1

niejawne deklaracji (gdzie funkcja nierejestrowana jest przyjęte, aby powrócić int) nie są już dozwolone w C99.

Powiedziawszy to, gcc nie przerwie kompilacji.

Spróbuj dołączyć strings.h dla bzero, zobacz także odpowiedź paxdiablo.

+0

Myślę, że tak się dzieje: nic tak naprawdę nie jest * różne *, ale domyślne definicje funkcji nie są zgłaszane bez standardów C99. Co oznacza, że ​​moje #includes po prostu nie działają z jakiegokolwiek powodu. Piekło ... –

3

Błąd dostajesz sprawia, że ​​brzmi jak funkcje jesteś korzystających nie są zadeklarowane. Czy na pewno dołączasz do nich poprawne nagłówki?

Ponadto użycie opcji -std=c99 może wyłączyć niektóre rozszerzenia, które nie są częścią standardu. Żadna z wymienionych funkcji nie jest częścią standardu C. Jeśli nie możesz znaleźć osobnych nagłówków dla nich, możesz spróbować -std=gnu99.

2

-std=c99 powoduje, że nagłówki pomijają wszystko, co może kolidować z użyciem nazw spoza obszaru zastrzeżonego C99, w tym ze wszystkimi standardowymi funkcjami POSIX. Przenośny sposób wysyłania żądań do nagłówków daje interfejsom POSIX zdefiniowanie _POSIX_C_SOURCE na wartość odpowiadającą żądanej wersji POSIX. Do najnowszej POSIX (2008), to znaczy:

#define _POSIX_C_SOURCE 200809L 

lub w wierszu poleceń:

-D_POSIX_C_SOURCE=200809L 

Edit: Wydaje funkcje chcesz nie są w bazie POSIX ale w Opcja XSI, więc powinieneś zdefiniować _XOPEN_SOURCE na odpowiednią wartość (700 jest najnowsza), aby je uzyskać. To też może być wykonane z linii poleceń lub pliki źródłowe (ale jeśli z plików źródłowych, to musi być zrobione przed tym wszelkich nagłówków systemowych.

1

pytasz za zgodność standardów, a nie C99 zdefiniuj srand48() jako funkcję dostarczoną przez <stdlib.h>.

dla biblioteki GNU C, można zażądać dodatkowych funkcji poprzez zdefiniowanie jednego lub więcej z wymienionych opcji w komentarzu na górze /usr/include/features.h, albo przez #define przed wami #include, lub z -D flagę gcc.

Dla srand48() (i drand48()) prawdopodobnie zechcesz albo -D_XOPEN_SOURCE=500 lub -D_SVID_SOURCE (lub #define _XOPEN_SOURCE 500 itd w plikach źródłowych).

bzero() i close() powinien pracować nawet z -std=c99 jeśli #include udokumentowane pliki nagłówkowe dla nich, które są <strings.h> i <unistd.h> odpowiednio.

Powiązane problemy