Qual è la differenza tra __PRETTY_FUNCTION__, __FUNCTION__, __func__?

Qual è la differenza tra __PRETTY_FUNCTION__ , __FUNCTION__ , __func__ e dove sono documentati? Come posso decidere quale usare?

__func__ è un identificatore implicitamente dichiarato che si espande in una variabile di matrice di caratteri contenente il nome della funzione quando viene utilizzata all’interno di una funzione. È stato aggiunto a C in C99. Da C99 §6.4.2.2 / 1:

L’identificatore __func__ è implicitamente dichiarato dal traduttore come se, immediatamente dopo la parentesi di apertura di ogni definizione di funzione, la dichiarazione

 static const char __func__[] = "function-name"; 

è apparso, dove nome-funzione è il nome della funzione che include lessicamente. Questo nome è il nome disadorno della funzione.

Si noti che non è una macro e non ha alcun significato speciale durante la preelaborazione.

__func__ stato aggiunto a C ++ in C ++ 11, dove è specificato come contenente “una stringa defi nita all’implementazione” (C ++ 11 §8.4.1 [dcl.fct.def.general] / 8), che non è abbastanza utile come la specifica in C. (La proposta originale di aggiungere __func__ a C ++ era N1642 ).

__FUNCTION__ è un’estensione pre-standard supportata da alcuni compilatori C (inclusi gcc e Visual C ++); in generale, dovresti usare __func__ dove è supportato e usare solo __FUNCTION__ se stai usando un compilatore che non lo supporta (per esempio, Visual C ++, che non supporta C99 e non supporta ancora tutto il C ++ 0x, non fornisce __func__ ).

__PRETTY_FUNCTION__ è un’estensione gcc che è per lo più uguale a __FUNCTION__ , eccetto che per le funzioni C ++ contiene il nome “carino” della funzione che include la firma della funzione. Visual C ++ ha un’estensione simile (ma non del tutto identica), __FUNCSIG__ .

Per le macro non standard, ti consigliamo di consultare la documentazione del compilatore. Le estensioni di Visual C ++ sono incluse nella documentazione MSDN delle “macro predefinite” del compilatore C ++. Le estensioni della documentazione di gcc sono descritte nella pagina della documentazione di gcc “Nomi di funzione come stringhe”.

Nonostante questo non risponda completamente alla domanda originale, è ciò che la maggior parte delle persone che google potrebbe voler vedere

Per GCC:

 [email protected]:~$ cat test.cpp #include  int main(int argc, char **argv) { std::cout << __func__ << std::endl << __FUNCTION__ << std::endl << __PRETTY_FUNCTION__ << std::endl; } [email protected]:~$ g++ test.cpp [email protected]:~$ [email protected]:~$ ./a.out main main int main(int, char**) 

__PRETTY_FUNCTION__ gestisce le funzionalità di C ++: classi, spazi dei nomi, modelli e sovraccarico

 #include  namespace N { class C { public: template  static void f(int i) { std::cout << __func__ << std::endl << __FUNCTION__ << std::endl << __PRETTY_FUNCTION__ << std::endl; } template  static void f(double f) { std::cout << __PRETTY_FUNCTION__ << std::endl; } }; } int main() { N::C::f(1); N::C::f(1.0); } 

Output GCC 7.2 g++ -std=gnu++98 :

 f f static void N::C::f(int) [with T = char] static void N::C::f(double) [with T = void] 

__func__ è documentato nello standard C ++ 0x nella sezione 8.4.1. In questo caso è una variabile locale della funzione predefinita del modulo:

 static const char __func__[] = "function-name "; 

dove “nome della funzione” è specfic di implementazione. Ciò significa che ogni volta che si dichiara una funzione, il compilatore aggiungerà questa variabile implicitamente alla propria funzione. Lo stesso vale per __FUNCTION__ e __PRETTY_FUNCTION__ . Nonostante il loro uppercasing, non sono macro. Sebbene __func__ sia un’aggiunta a C ++ 0x

 g++ -std=c++98 .... 

compilerà ancora il codice usando __func__ .

__PRETTY_FUNCTION__ e __FUNCTION__ sono documentati qui http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names . __FUNCTION__ è solo un altro nome per __func__ . __PRETTY_FUNCTION__ è uguale a __func__ in C ma in C ++ contiene anche la firma del tipo.

Per quelli che si chiedono come va in VS.

Aggiornamento MSVC 2015 1, versione cl.exe 19.00.24215.1:

 #include  template struct A { template static void f() { std::cout << "from A::f():" << std::endl << __FUNCTION__ << std::endl << __func__ << std::endl << __FUNCSIG__ << std::endl; } }; void main() { std::cout << "from main():" << std::endl << __FUNCTION__ << std::endl << __func__ << std::endl << __FUNCSIG__ << std::endl << std::endl; A::f(); } 

produzione:

 da main ():
 principale
 principale
 int __cdecl main (void)

 da A :: f ():
 A  :: f
 f
 void __cdecl A  :: f  (void)

L’utilizzo di __PRETTY_FUNCTION__ innesca l’errore dell’identificatore non dichiarato, come previsto.