poniżej podanego programu działa bez włączania <stdio.h>
? Dlaczego to działa?bez uwzględnienia <stdio.h>
int main()
{
printf("integra");
return 0;
}
poniżej podanego programu działa bez włączania <stdio.h>
? Dlaczego to działa?bez uwzględnienia <stdio.h>
int main()
{
printf("integra");
return 0;
}
Niektóre (stare?) Kompilatory nie wymagają prototypów przed wywołaniem funkcji.
Często dopuszczalne jest używanie niezadeklarowanych funkcji w C (ale nie sądzę w tym przypadku), ale niezalecane . – Philipp
w starszym standardzie, funkcja nieoznakowana przyjmuje argument int
i zwraca wartość. Twój char*
ma ten sam rozmiar (32-bitowy) co int
, więc wszystko działa.
Po prostu tego nie rób.
Witam, działa również main() { if (isalnum (';')) printf ("znak; nie jest alfanumeryczny"); if (isalnum ("A")) printf ("znak A jest alfanumeryczny"); return 0; } – venkat
daj mi jasne wyjaśnienie – venkat
sprawdź swoją stronę podręcznika. 'isalpha()' to 'int isalpha (int)'. ten mecz, co powiedziałem. –
printf() jest zdefiniowana tylko w libc.so
dynamiczny linker rozwiąże printf symbol() w libc, ponieważ nie obejmowały go
libc jest domyślny w gcc dla każdego programu
Dynamiczny linker rozwiąże symbol printf **, nawet jeśli posiadasz deklarację **. (Pomyśl o tym!) – user562374
Gdy używasz funkcji, która nie została zadeklarowana, kompilator przyjmie, że ta funkcja zwraca wartość int
i przyjmuje nieokreśloną, ale ustaloną liczbę argumentów.
Jeśli to przyporządkowanie pasuje do definicji funkcji, a podane argumenty również pasują (modulo domyślne promocje argumentów) do parametrów oczekiwanych przez funkcję, to wszystko jest w porządku.
Jeśli założenie jest niepoprawne (np. Dla printf
, która jest funkcją variadic) lub gdy argumenty nie są zgodne, wyniki są niezdefiniowane. Jedną z nieprzyjemnych rzeczy o nieokreślonym zachowaniu jest to, że może działać zgodnie z oczekiwaniami.
Jak zauważył Abi, twój kod buduje się pomyślnie bez włączania stdio.h, ponieważ linker domyślnie stosuje systemową bibliotekę std dla niezdefiniowanego symbolu (printf
). GCC zwykle ostrzega Cię o takich przypadkach.
Let test.c być: test.c
1: int main()
2: {
3: printf("test\n");
4: return 0;
5: }
Budynek z GCC 4.2.1 na Mac OSX:
$ gcc test.c
test.c: In function ‘main’:
test.c:3: warning: incompatible implicit declaration of built-in function ‘printf’
$ ./a.out
test
Można wyłączyć tę domyślną łączenie poprzez określenie opcji linkera GCC -nostdlib
(lub -nodefaultlibs
) wraz z -lgcc
(jak instrukcja GCC zaleca)
$ gcc -nostdlib -lgcc test.c
test.c: In function ‘main’:
test.c:3: warning: incompatible implicit declaration of built-in function ‘printf’
Undefined symbols:
"_puts", referenced from:
_main in cc3bvzuM.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
Definicja printf() znajduje się w libc.so, a dynamiczny linker zajmie się tym, nawet jeśli nie uwzględnisz pliku nagłówkowego. Podczas kompilacji, printf() będzie niezdefiniowanym symbolem i zakłada, że może znaleźć definicję później w bibliotece libc. Plik nagłówkowy po prostu nadaje typ proto i tłumi kompilator (ostrzeżenia), stwierdzając, że definicja prototypu jest obecna w glibc. Zasadniczo pliki nagłówkowe są uwzględniane tylko po to, aby upewnić się, że definicje są dostępne w naszych bibliotekach, aby pomóc programistom.
"Dlaczego to działa?" nie jest poprawnym pytaniem, gdy napisałeś kod z niezdefiniowanym zachowaniem. –
@R ..: może to powód, by zakładać, że venkat sam nie wymyślił tego pytania, ale jego nauczyciel? – Bart
Możliwy duplikat [Dlaczego #include jest \ * not \ * wymagany do użycia printf()?] (Http: // stackoverflow.com/questions/336814/why-include-stdio-h-is-not-required-to-use-printf) –
vaxquis