2012-06-18 10 views
7

Stavo guardando un codice che un amico mi ha mandato e ha detto: "Compila, ma non funziona". Ho visto che ha usato le funzioni senza le parentesi, qualcosa di simile:Perché il compilatore C++ non si lamenta quando utilizzo le funzioni senza parentesi?

void foo(){ 
    cout<< "Hello world\n"; 
} 

int main(){ 
    foo; //function without parentheses 
    return 0; 
} 

La prima ho detto è stata "Utilizzare le parentesi, si devono". E poi ho testato quel codice - lo fa compilare, ma quando viene eseguito non funziona (non viene mostrato "Hello world").

Allora, perché lo fa compilare (nessun avvertimento a tutti dal compilatore GCC 4.7 ), ma non funziona?

+0

In realtà funziona. 'pippo' viene trattato così com'è, un puntatore a funzione. La riga 'pippo;' è solo una riga senza effetto. Se si attivano gli avvisi al massimo si dovrebbe ottenere un avviso su una dichiarazione senza effetto. – RedX

+0

Vedo * "warning: statement è un riferimento, non una chiamata, alla funzione 'foo'" * e * "warning: l'istruzione non ha effetto" *. Probabilmente vuoi compilare con -Wall -Wextra – Flexo

+3

(Per le domande future vale la pena inserire il '#include ' e qualsiasi spazio dei nomi anche per completare il tuo esempio) – Flexo

risposta

12

Si avvisa sicuramente se si imposta il livello di avviso abbastanza alto.

Un nome di funzione valuta l'indirizzo della funzione ed è un'espressione legale. Di solito viene salvato in un puntatore di funzione,

void (*fptr)() = foo; 

ma non è necessario.

11

È necessario aumentare il livello di avviso che si utilizza. foo; è un'istruzione di espressione valida (il nome di una funzione viene convertita in un puntatore alla funzione denominata) ma non ha alcun effetto.

Io di solito uso -std=c++98 -Wall -Wextra -pedantic che dà:

<stdin>: In function 'void foo()': 
<stdin>:2: error: 'cout' was not declared in this scope 
<stdin>: In function 'int main()': 
<stdin>:6: warning: statement is a reference, not call, to function 'foo' 
<stdin>:6: warning: statement has no effect 
3
foo; 

Tu non sei in realtà 'usando' la funzione qui. Stai solo usando l'indirizzo di esso. In questo caso, lo stai prendendo ma non lo utilizzi veramente.

Gli indirizzi delle funzioni (ad esempio i loro nomi, senza parentesi) sono utili quando si desidera passare quella funzione come richiamata ad un'altra funzione.