Czy ten niewinny Program patrząc powołać niezdefiniowanej zachowanie:Czy wywołanie printf bez odpowiedniego prototypu wywołuje niezdefiniowane zachowanie?
int main(void) {
printf("%d\n", 1);
return 0;
}
Czy ten niewinny Program patrząc powołać niezdefiniowanej zachowanie:Czy wywołanie printf bez odpowiedniego prototypu wywołuje niezdefiniowane zachowanie?
int main(void) {
printf("%d\n", 1);
return 0;
}
Tak powołując printf()
bez odpowiedniego prototypu (ze standardowego nagłówka <stdio.h>
lub z prawidłowo pisemnej deklaracji a) powołuje niezdefiniowanej zachowanie.
Jak udokumentowano w C11 załączniku J (informacyjny tylko)
J2 zachowanie niezdefiniowane
- Dla wywołania funkcji bez prototypu funkcji w zakresie, w którym funkcja jest określona w funkcji prototyp, prototyp kończy się wielokropkiem lub typy argumentów po promocji nie są zgodne z typami parametrów (6.5.2.2).
Ten załącznik nie jest normatywny, ale wyraźnie dokumentuje powyższy kod jako przykład niezdefiniowanego zachowania.
W bardziej praktyczne słowy, w przypadku braku prototypu printf
kompilator generuje sekwencję dzwonienia jak printf
zdefiniowanego jako int printf(const char*, int)
, które mogą być bardzo różne i niezgodne z aktualną wykonania printf
w standardowym biblioteki zdefiniowane jako int printf(const char restrict *format, ...)
.
Starożytne ABI były na tyle regularne, że nie stanowiłoby to problemu, ale nowoczesne (np. 64-bitowe) ABI używają bardziej wydajnych sekwencji wywołujących, które czynią powyższy kod zdecydowanie niepoprawnym.
W konsekwencji, ten słynny klasyczny program C zawiedzie też bez #include <stdio.h>
lub przynajmniej właściwy prototyp printf
:
int main(void) {
printf("Hello world\n"); // undefined behavior
return 0;
}
drobne zastrzeżenie: Wywoływanie 'printf()' bez odpowiedniej prototyp wywołuje niezdefiniowany zachowanie. Nieważne, czy pochodzi z ''. Program może alternatywnie dostarczyć swoją własną prototypową deklarację 'printf'. –
hvd
@hvd: zgodził się, będę przeredagować odpowiedź. Prototyp może pochodzić z innego źródła, ale musi być zgodny z rzeczywistą definicją 'printf' w bibliotece C. – chqrlie
Cóż, ściśle mówiąc, odpowiedź na twoje pytanie (patrz tytuł) brzmi * nie *. Jak sam to zauważyłeś, plik nagłówkowy [zamiast "" może być zastąpiony przez * poprawnie napisaną deklarację *. –
Matsmath