Si consideri il seguente codice:gcc sta eseguendo le dichiarazioni di funzione implicite in modo non corretto nella modalità c99?
int main (void) {
int i = xyzzy();
return i;
}
int xyzzy (void) {
return 42;
}
Ora, anche se il prototipo per xyyzy
è sconosciuta al punto di utilizzo, questo funziona in modalità C89, perché il tipo di ritorno di default di una funzione che non ha prototipo è int
così la prototipo di funzione implicita e funzione reale sono compatibili.
E, infatti, se si cambia il tipo di ritorno della funzione da float
, si ottiene (come previsto):
testprog.c:6: error: conflicting types for 'xyzzy'
testprog.c:2: error: previous implicit declaration of 'xyzzy' was here
perché il prototipo implicita e la funzione attuale non è più partita.
Il codice originale compilato con gcc --std=c89 --pedantic -Wall -Wextra
mi dà solo l'avvertimento:
testprog.c: In function 'main':
testprog.c:2: warning: implicit declaration of function 'xyzzy'
che si prevede, a causa C89 ha questo da dire in 3.7.1 Function definitions
:
extern int max (int a, int b) {...}: Qui
extern
è l'identificatore di classe di archiviazione eint
è l'identificatore di tipo (ognuno dei quali può essere omesso in quanto tali sono i valori predefiniti).
e in 3.3.2.2 Function calls
:
Se l'espressione che precede la lista degli argomenti tra parentesi in una chiamata di funzione consiste unicamente di un identificatore, e se nessuna dichiarazione è visibile per questo identificatore, l'identificatore è implicitamente dichiarata esattamente come se, nel blocco più interno contenente la chiamata di funzione, la dichiarazione extern int identifier(); apparso.
Quindi l'uso di una funzione prima di dichiarare che sicuramente risultati nel prototipo di default in fase di creazione.
Tuttavia, di queste due frasi sono state rimosse in C99 e noi invece trovare in 6.5.2.2 Function calls
(il mio grassetto):
Se l'espressione che indica la funzione chiamata è di tipo puntatore a funzione che restituisce un oggetto digita, l'espressione di chiamata di funzione ha lo stesso tipo di quel tipo di oggetto e ha il valore determinato come specificato in 6.8.6.4. In caso contrario, la chiamata di funzione ha tipo void.
ho capito bene a dire che, se non c'è nessuna dichiarazione in vista quando si tenta di chiamare una funzione, è implicitamente dichiarato con un tipo void
ritorno.
Tuttavia, durante la compilazione con gcc --std=c99 --pedantic -Wall -Wextra
, viene visualizzato lo stesso avviso relativo alla dichiarazione implicita.
Nel caso in cui C99 non abbia dichiarato implicitamente tale funzione come risposta void
?Se lo fosse, mi sarei aspettato un errore previous implicit declaration
simile a quello che ho ottenuto quando ho provato a ridichiarlo come restituendo float
.
È gcc
interrotto qui o mi manca qualcosa nello standard?
compilatore sun/oracle cc con opzione -xc99 e utilizzando float per la funzione restituisce corrente: function (void) return float; precedente: function() che restituisce int: "pax.c", riga 2; Penso che sia difficile che 2 compilatori mostrino la stessa interpretazione errata dello standard, anche se non è impossibile: gli standard dovrebbero evitare un linguaggio che rende difficile capire come dovrebbero essere le cose! – ShinTakezou
@Shin, sembra che anche il compilatore Sun abbia come valore predefinito "return int" anche in modalità C99, nel qual caso potrebbe essere che sto leggendo lo standard in modo errato. Non riuscivo a capire dove. – paxdiablo
Stai leggendo potrebbe non essere corretto; non sarebbe retrocompatibile. In C99, si suppone di avere una dichiarazione (preferibilmente una dichiarazione prototipo) della funzione, o la definizione della funzione, visibile nell'ambito. Nessuna dichiarazione nello scope richiede una diagnostica (e potrebbe fallire la compilazione). Prendo atto che stai citando lo standard ANSI C89 - i numeri di sezione in ISO C90 erano diversi. –