Как получить номер строки ошибки в программе на С++
Я хочу обрабатывать ошибки в моей программе на С++, поэтому я создал некоторые классы исключений для управления этими ошибками, но я хочу указать, в какой строке в моей программе произошла ошибка.
Я передал макрос LINE конструктору моего класса исключений.
Например:
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
}
}
В этом примере я могу получить только номер LINE B, но хочу получить номера LINE A и LINE C.
Любая идея, где и как использовать макрос LINE
Спасибо.
Ответы
Ответ 1
Вы ищете трассировку стека, и нет никакого переносного способа ее получить. Что-то похожее может быть достигнуто с помощью:
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__);
Затем сразу после начала каждой функции (или точки интереса) вы просто добавляете строку... например
int myFunction(int x)
{
MARK_FUNCTION
...
}
Используя этот подход в обработчиках ошибок, вы можете узнать, кто был вызван кем и т.д. (конечно, вы будете знать только функции или места, которые были связаны с MARK_FUNCTION). Если это необходимо только во время тестирования (а не в производстве), то, вероятно, вам следует просто включить дампы ядра и научиться запускать отладчик в анализе после вскрытия.
Ответ 2
Строка C была бы почти невозможна (я не могу придумать способ... за исключением того, что передал второй аргумент f
, __LINE__
.
Линия А выглядит следующим образом:
void f(int i){ const int lineA = __LINE__;
if(i<0)
throw(OutOfRange("message", __LINE__); // LINE B
}
Ответ 3
Вам нужна трассировка стека и отладчик. В стандартном С++ нет способа найти строку C, не передавая ее в качестве аргумента (f(-6, __LINE__)
), и никак не может найти строку A.
Ответ 4
Структура CPPUNit использует макросы вместо функций. Таким образом, вы можете легко получить номер строки в том же месте, где вызывается макрос.
Я не думаю, что это правильный подход в общем смысле, но вам может показаться интересным взглянуть на то, как это сделали разработчики CPPUnit.