¿Cuál es la diferencia entre __PRETTY_FUNCTION__, __FUNCTION__, __func__?

¿Cuál es la diferencia entre __PRETTY_FUNCTION__ , __FUNCTION__ , __func__ y dónde están documentados? ¿Cómo decido cuál usar?

__func__ es un identificador declarado implícitamente que se expande a una variable de matriz de caracteres que contiene el nombre de la función cuando se usa dentro de una función. Se agregó a C en C99. De C99 §6.4.2.2 / 1:

El __func__ es declarado implícitamente por el traductor como si, inmediatamente después de la llave de apertura de cada definición de función, la statement

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

apareció, donde nombre-función es el nombre de la función que encierra léxicamente. Este nombre es el nombre sin adornos de la función.

Tenga en cuenta que no es una macro y no tiene un significado especial durante el preprocesamiento.

__func__ se agregó a C ++ en C ++ 11, donde se especifica que contiene “una cadena definida por la implementación” (C ++ 11 §8.4.1 [dcl.fct.def.general] / 8), que no es del todo tan útil como la especificación en C. (La propuesta original para agregar __func__ a C ++ era N1642 ).

__FUNCTION__ es una extensión preestablecida que admiten algunos comstackdores de C (incluidos gcc y Visual C ++); en general, debe usar __func__ donde sea compatible y solo use __FUNCTION__ si está utilizando un comstackdor que no lo admite (por ejemplo, Visual C ++, que no es compatible con C99 y aún no es compatible con todo C ++ 0x, no proporciona __func__ ).

__PRETTY_FUNCTION__ es una extensión de gcc que es casi igual a __FUNCTION__ , excepto que para las funciones de C ++ contiene el nombre “bonito” de la función, incluida la firma de la función. Visual C ++ tiene una extensión similar (pero no del todo idéntica), __FUNCSIG__ .

Para las macros no estándar, querrá consultar la documentación de su comstackdor. Las extensiones de Visual C ++ se incluyen en la documentación de MSDN de las “Macros predefinidas” del comstackdor C ++. Las extensiones de documentación de gcc se describen en la página de documentación de gcc “Nombres de funciones como cadenas”.

A pesar de que esto no responde completamente a la pregunta original, es a lo que la mayoría de las personas que buscaron google esto querían ver

Para GCC:

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

__PRETTY_FUNCTION__ maneja las características de C ++: clases, espacios de nombres, plantillas y sobrecarga

 #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); } 

Salida 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__ está documentado en el estándar C ++ 0x en la sección 8.4.1. En este caso, es una variable local de función predefinida de la forma:

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

donde “nombre de función” es especificación de implementación. Esto significa que cada vez que declare una función, el comstackdor agregará esta variable implícitamente a su función. Lo mismo es cierto para __FUNCTION__ y __PRETTY_FUNCTION__ . A pesar de su uppercasing, no son macros. Aunque __func__ es una adición a C ++ 0x

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

todavía comstackrá código usando __func__ .

__PRETTY_FUNCTION__ y __FUNCTION__ están documentados aquí http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names . __FUNCTION__ es solo otro nombre para __func__ . __PRETTY_FUNCTION__ es lo mismo que __func__ en C, pero en C ++ también contiene la firma de tipo.

Para aquellos, que se preguntan cómo va en VS.

Actualización 1 de MSVC 2015, cl.exe versión 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(); } 

salida:

 de main ():
 principal
 principal
 int __cdecl main (void)

 de A :: f ():
 A  :: f
 F
 void __cdecl A  :: f  (void)

El uso de __PRETTY_FUNCTION__ desencadena un error de identificador no declarado, como se esperaba.