2010-12-30 8 views
11

Quiero manejar errores en mi programa C++, así que creé algunas clases de excepción para administrar esos errores, pero quiero especificar en qué línea de mi programa se produjo el error.cómo obtener el número de línea de error en el programa C++

Pasé LINE macro al constructor de mi clase de excepción.

Por ejemplo:

void f(int i){ // LINE A 
    if(i<0) 
    throw(OutOfRange("message", __LINE__); // LINE B 
} 

void main(){ 

    try{ 
    f(-6); // LINE C 
    } 
    catch(const OutOfRange& error){ 
    //do something 
    } 

} 

En este ejemplo sólo puedo obtener el número de la línea B, pero quiero obtener los números de las líneas A y C.

Cualquier idea, dónde y cómo usar LINE macro ??

Gracias.

+1

Desea una stacktrace/traceback. – delnan

+0

http://www.decompile.com/cpp/faq/file_and_line_error_string.htm – anno

Respuesta

8

Usted está buscando para un rastro de pila y el no hay forma portátil de obtenerlo. Algo algo similar se puede lograr con:

struct SourcePoint 
{ 
    const char *filename; 
    int line; 
    SourcePoint(const char *filename, int line) 
     : filename(filename), line(line) 
    { } 
}; 

std::vector<SourcePoint> callstack; 

struct SourcePointMarker 
{ 
    SourcePointMarker(const char *filename, int line) 
    { 
     callstack.push_back(SourcePoint(filename, line); 
    } 

    ~SourcePointMarker() 
    { 
     callstack.pop_back(); 
    } 
} 

#define MARK_FUNCTION \ 
    SourcePointMarker sourcepointmarker(__FILE__, __LINE__); 

A continuación, justo después del comienzo de cada función (o punto de interés) que acaba de añadir una línea ... por ejemplo

int myFunction(int x) 
{ 
    MARK_FUNCTION 
    ... 
} 

uso de este enfoque en sus manejadores de errores pueden saber quién fue llamado por quién y así sucesivamente (por supuesto, usted solo sabrá funciones o lugares que hayan sido equipados con MARK_FUNCTION). Si esto solo es necesario durante las pruebas (y no en la producción), entonces probablemente solo deba habilitar los volcados centrales y aprender a ejecutar un depurador en el análisis post-mortem.

+1

sí, eso es lo que estoy buscando, lo intentaré bien ahora, muchas gracias. – CHAKRI

1

Línea C sería casi imposible (no puedo pensar en una manera ... excepto pasando un segundo argumento para f, __LINE__

línea A de la siguiente manera:.

void f(int i){ const int lineA = __LINE__; 
    if(i<0) 
    throw(OutOfRange("message", __LINE__); // LINE B 
} 
+0

te refieres a void f (int i) {const int lineA = __LINE__; if (i <0) throw (OutOfRange ("message", lineA); // LINE B } – CHAKRI

+0

gracias por su respuesta, pero creo que para "LINE C" no es imposible porque la mayoría de los compiladores lo usan !! – CHAKRI

+1

@CHAKRI: El compilador puede hacer muchas, muchas, muchas cosas que no se pueden hacer en Standard C++. – Puppy

1

Usted necesita una traza de pila y un depurador. No hay forma en Estándar C++ de que pueda encontrar la línea C sin pasarla como argumento (f(-6, __LINE__)), y no hay manera de que pueda encontrar la línea A.

+0

+1, pero yo diría "un seguimiento de pila * o * un depurador", ya que un rastro de la pila se puede obtener incluso sin un depurador externo (véase, por ejemplo, la función 'backtrace'). –

+0

ok tal vez lo pasé como argumento. Gracias – CHAKRI

1

El marco CPPUNit utiliza macros en lugar de funciones. De esta forma, puede obtener fácilmente el número de línea en el mismo lugar donde se llama la macro.

No creo que sea un enfoque válido en un sentido general, pero puede que le resulte interesante echar un vistazo a la forma en que lo hicieron los desarrolladores de CPPUnit.

+0

+1. Mire la implementación de la macro assert(); He creado una macro assertion() similar, que arroja una excepción std :: logic_error en lugar de llamar a std :: abort() cuando falla una aserción. – Raedwald

+0

ok Lo veré, gracias – CHAKRI

Cuestiones relacionadas