2011-10-04 16 views
8

Cuando uso la macro/variable __FUNCTION__ para imprimir la información de depuración, parece haber una diferencia en lo que genera cuando usa el compilador de Microsoft C++ y gcc. Por ejemplo, usando el siguiente código trivial:¿Cómo imito la versión de Microsoft de __FUNCTION__ usando gcc?

class Foo 
{ 
    public: 
     void Bar(int a, int b, int c) 
     { 
      printf ("__FUNCTION__ = %s\n", __FUNCTION__); 
     } 
}; 

int main (void) 
{ 
    Foo MyFoo; 

    MyFoo.Bar(); 

    return 0; 
} 

Usando el compilador de Visual C++ Microsoft, consigo

__FUNCTION__ = Foo::Bar 

mientras que al compilar con gcc (en este caso en el Mac), consigo

El segundo ejemplo no es ideal porque con bastante frecuencia tengo varias clases con, por ejemplo, Init() y Uninit() y en una salida de depuración rastreamos su virtua Es imposible saber cuál de estos ha sido llamado ya que falta el nombre de la clase. Ahora, sé que se puede utilizar el __PRETTY_FUNCTION__ en lugar de __FUNCTION__ para obtener algo así como

__PRETTY_FUNCTION__ = void Foo::Bar(int, int, int) 

Lo cual está bien, pero es un poco demasiado prolijo para lo que necesito y se hace un poco larga para las funciones con una gran cantidad de parámetros .

Así que mi pregunta es (por fin), ¿hay alguna forma de que la salida parezca simplemente Foo::Bar usando gcc, como en el ejemplo anterior?

+0

tengo curiosidad ya que nunca he necesitado esta macro, ¿por qué lo necesita? ¿Su compilador/suite de pruebas/comprobador de memoria no le dice la línea exacta de código donde ocurre el problema? - si es para iniciar sesión, sugiero que se escriban registros que sean idénticos sin importar el compilador utilizado, ya que entonces puede escribir herramientas de coincidencia de patrones para analizar los registros. – Tom

+0

posible duplicado de [¿Cuál es la diferencia entre __PRETTY_FUNCTION__, __FUNCTION__, __func__?] (http://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func) –

+0

No es un duplicado - esa pregunta no tiene nada que decir acerca de cómo obtener un estilo de Microsoft cadena fuera de GCC. –

Respuesta

3

Si lo está utilizando para el seguimiento, siempre puede usar typeid(T).name() y solo compilar condicionalmente por plataforma. Ciertamente no es tan conveniente como la macro, pero podría funcionar.

vagamente similar a __CLASS__ macro in C++

+0

Al recorrer esta ruta con GCC, la [biblioteca de demanda] (http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html) puede ser útil. – user786653

2

El nombre-función sancionado por el estándar se define como sigue:

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

Ejemplo:

#include <iostream> 

namespace meh { 
    void foobar() { std::cout << __func__ << std::endl; } 
}; 

struct Frob { 
    void foobar() { std::cout << __func__ << std::endl; } 
    static void barfoo() { std::cout << __func__ << std::endl; } 
}; 

int main() { 
    std::cout << __func__ << std::endl; 
    meh::foobar(); 
    Frob().foobar(); 
    Frob::barfoo(); 
} 

Sin embargo, la salida con g ++:

main 
foobar 
foobar 
barfoo 

Sin embargo, lo que se comportamiento válido de C++:

§ 8.4.1, 8: La variable predefinida de función local __func__ se define como si se hubiera proporcionado una definición del formulario static const char __func__[] = "function-name "; , donde nombre-función es una cadena definida por la implementación. No se especifica si dicha variable tiene una dirección distinta a la de cualquier otro objeto en el programa

Es decir, no puede confiar en su valor. Si desea utilizar extensiones no portátiles, eche un vistazo a una pregunta similar: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?.

Cuestiones relacionadas