2015-01-01 16 views
5

E 'K & R-C ed ecco il codice: http://v6shell.org/history/if.crichiamare una funzione senza discutere, anche se ha bisogno di una [K & R-C]

sguardo al principale metodo. C'è questa riga "if (exp())".

Ma la funzione exp è dichiarata come: exp (s). Quindi ha bisogno di una discussione.

Perché funziona? E perché lo faresti?

+0

il compilatore restituisce un errore "troppo pochi argomenti per funzionare exp()" ...! sto compilando usando il compilatore g ++ ... –

+3

@Madan: Usare G ++ su (antico) codice C non è un test molto preciso. –

+0

grazie per esserti ricordato di questo .. :) –

risposta

8

In definitiva, si tratta di un bug nel comando di supporto shell V6 di Unix, if.

Il codice per la funzione è:

exp(s) { 
    int p1; 

    p1 = e1(); 
    if (eq(nxtarg(), "-o")) return(p1 | exp()); 
    ap--; 
    return(p1); 
} 

Il parametro funzione s, implicitamente di tipo int (come la funzione iteself), è in realtà non utilizzato nella funzione, quindi il baco è la presenza di s , non l'assenza di un argomento nelle chiamate a exp(). Tutte le chiamate con zero argomenti reali sono corrette.

+0

Quindi potrei chiamare una funzione con tutti gli argomenti che voglio, se la funzione chiamata non usa nessuno di questi argomenti non ci saranno problemi? – Joey

+1

@Kevin: sorta, ma è uno spreco passare argomenti che non saranno usati. Tuttavia, è l'origine delle diverse convenzioni di chiamata per le funzioni in C su MS Windows. Poiché la funzione C non conosce quanti argomenti sono stati passati, non può generare il codice di pulizia dello stack per la sua chiamata, diversamente dalla funzione Pascal (ad esempio). Quindi, lo stack deve essere reintegrato dal codice nelle funzioni di chiamata (il che significa che la pulizia viene scritta ogni volta che viene chiamata la funzione), piuttosto che all'interno della funzione stessa (il che significherebbe che la pulizia viene scritta una sola volta). –

+0

Avete qualche fonte per la "funzione C non so quanti argomenti sono stati passati" o cosa ha detto alex "" Non richiede nemmeno i parametri di funzione da controllare. ""? Dove posso leggere questo? Qualche Wikipedia o articolo? – Joey

2

Questo perché in c

Il compilatore non sarà in grado di eseguire in fase di compilazione dei tipi di argomento e arity quando la funzione viene applicata ad alcuni argomenti. Ciò può causare problemi

chiama una funzione non dichiarato è lo stile povero di C (Vedere questo) e illegale in C++

per esempio-

#include<stdio.h> 

void f(int x); 

int main() 
{ 
    f(); /* Poor style in C, invalid in C++*/ 
    getchar(); 
    return 0; 
} 

void f(int x) 
{ 
    printf("%d", x); 
} 

Questo programma funziona, ma non dovrebbe essere utilizzato.Vedere questo collegamento Wiki per ulteriori informazioni.

+1

citazione necessaria per il preventivo. – ryanpattison

+0

@rpattiso il link che stavo avendo è ora morto:/ – Ankur

+0

In questo caso chiamano la funzione usando 'f()', che è più dubbia. La tua risposta non risponde al vero problema, che sta chiamando una funzione con meno argomenti di quelli accettati dalla sua definizione. – interjay

6

Se si guarda la definizione:

exp(s) { 
    int p1; 

    p1 = e1(); 

    if (eq(nxtarg(), "-o")) return(p1 | exp()); 
     ap--; 

    return(p1); 
} 
  1. s non viene utilizzato
  2. C non richiede la compilazione tipo di tempo controllo. Non richiede nemmeno che i parametri di funzione siano controllati. Tutto è a/serie di byte

Perché C non esegue nessuno di questi controlli? Da quello che ho sentito è che durante i primi anni di C i computer erano piuttosto deboli. Effettuare tali controlli richiederebbe più passaggi per eseguire la scansione del codice sorgente, il che sostanzialmente aumenta il tempo di compilazione di una quantità di n passaggi. Quindi esegue solo un passaggio e prende ogni nome così com'è, motivo per cui l'overloading delle funzioni non è supportato

Quindi, se le definizioni hanno fatto uso di s in qualche modo, molto probabilmente otterresti un errore di runtime orribile con meravigliose uscite sulla console

+0

Avete qualche ** sorgente ** per "Non richiede nemmeno i parametri di funzione da controllare."? – Joey

+0

Kevin: si noti che la shell Unix V6 è stata scritta prima del 1978 (immagino circa nel 1976). Questo è stato fatto prima della pubblicazione della prima edizione di K & R. A quel tempo, C-with-Classes, che divenne C++, era ancora in un lontano futuro; i prototipi semplicemente non esistevano. Le funzioni potrebbero essere dichiarate prima dell'uso, ma la dichiarazione era necessaria solo se il tipo di ritorno non era 'int'. Rispetto alla C moderna (che significa C99 o successiva) o al C++, le regole (o la sua mancanza) erano anarchiche. Ma le macchine erano minuscole secondo gli standard moderni: le grandi macchine potevano avere 1 megabyte (sì, MiB, non GiB) della memoria principale. –

Problemi correlati