2011-01-11 10 views
5

al di sotto del programma specificato funziona senza includere <stdio.h>? Perché funziona?senza includere <stdio.h>

int main() 
{ 
    printf("integra"); 
    return 0; 
} 
+1

"Perché funziona?" non è una domanda valida quando hai scritto il codice con un comportamento indefinito. –

+0

@R ..: forse questo è un motivo per supporre che venkat non ha avuto questa domanda da solo, ma il suo insegnante ha fatto ??? – Bart

+0

Possibile duplicato di [Perché #include è \ * non \ * necessario per utilizzare printf()?] (Http: // stackoverflow.it/questions/336814/why-include-stdio-h-is-not-required-to-use-printf) – vaxquis

risposta

1

Alcuni (vecchi?) Compilatori non richiedono prototipi prima di chiamare le funzioni.

+0

È spesso legale utilizzare le funzioni non dichiarate in C (ma non credo in questo caso), ma non è raccomandato . – Philipp

7

in standard precedente, la funzione non dichiarata assume l'argomento int e restituisce il valore. Il tuo char* ha la stessa dimensione (32-bit) come int, quindi tutto funziona.

Proprio non farlo.

+0

Ciao funziona anche int main() { if (isalnum (';')) printf ("carattere; non è alfanumerico"); if (isalnum ('A')) printf ("carattere A è alfanumerico"); return 0; } – venkat

+0

dammi chiarimenti spiegazione – venkat

+1

ricerca la tua pagina man. 'isalpha()' è 'int isalpha (int)'. questo corrisponde a quello che ho detto. –

5

printf() è definito solo in libc.so

Il linker dinamico risolverà il printf simbolo() nella libc poiché non l'ha incluso lo

libc è predefinito in gcc per ogni programma

+0

Il linker dinamico risolverà il simbolo printf ** anche se la dichiarazione è inclusa **. (Pensaci!) – user562374

1

Quando si utilizza una funzione che non è stata dichiarata, il compilatore assume che questa funzione restituisce un int e accetta un numero di argomenti non specificato, ma fisso.

Se questa ipotesi corrisponde alla definizione della funzione e se gli argomenti forniti corrispondono anche (modulo l'argomento predefinito promozioni) i parametri che la funzione si aspetta di ricevere, allora tutto va bene.
Se l'ipotesi non è corretta (come per printf, che è una funzione variadica), o quando gli argomenti non corrispondono, i risultati non sono definiti. Una delle cose brutte del comportamento indefinito è che può sembrare funzionare come previsto.

3

Come sottolineato da Abi, il codice viene compilato correttamente senza includere stdio.h poiché il linker è impostato per impostazione predefinita sulla libreria di sistema per il simbolo non definito (printf). GCC normalmente ti avviserà di questi casi.

Sia test.c essere: test.c

1: int main() 
2: { 
3: printf("test\n"); 
4: return 0; 
5: } 

Costruire con GCC 4.2.1 su 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 

è possibile disattivare questa linking di default specificando un'opzione GCC linker -nostdlib (o -nodefaultlibs) insieme a -lgcc (come il manuale di GCC raccomanda):

$ 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 
$ 
8

Definizione di printf() è presente in libc.so e il linker dinamico si prenderà cura di esso anche se non includi il file di intestazione. Durante la compilazione, printf() sarà un simbolo non definito e presuppone che possa trovare la definizione più avanti in libc. Il file di intestazione darà solo il proto-type e sopprimerà il compilatore (warnings) affermando che la definizione del prototipo è presente in glibc. Quindi, in pratica, i file di intestazione sono inclusi solo per assicurarsi che le definizioni siano disponibili nelle nostre librerie, per aiutare lo sviluppatore.

Problemi correlati