как получить номер строки ошибки в программе на C ++ - PullRequest
12 голосов
/ 30 декабря 2010

Я хочу обрабатывать ошибки в моей программе на С ++, поэтому я создал несколько классов исключений для управления этими ошибками, но я хочу указать, в какой строке в моей программе произошла ошибка.

Я передал макрос 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 macro ??

Спасибо.

Ответы [ 4 ]

8 голосов
/ 30 декабря 2010

Вы ищете трассировку стека, и нет портативного способа ее получить.Нечто похожее может быть достигнуто с помощью:

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).Если это необходимо только во время тестирования (а не в производственном процессе), то, вероятно, вам следует просто включить дампы ядра и научиться запускать отладчик в посмертном анализе.

1 голос
/ 30 декабря 2010

Платформа CPPUNit использует макросы вместо функций. Таким образом, вы можете легко получить номер строки в том же месте, где вызывается макрос.

Я не думаю, что это правильный подход в общем смысле, но вам может быть интересно посмотреть, как разработчики CPPUnit сделали это.

1 голос
/ 30 декабря 2010

Вам нужна трассировка стека и отладчик.В стандарте C ++ нет способа найти строку C, не передавая ее в качестве аргумента (f(-6, __LINE__)), и никак не найти строку A.

1 голос
/ 30 декабря 2010

Строка C была бы почти невозможна (я не могу придумать способ ... кроме как передать второй аргумент f, __LINE__.

Строка A выглядит следующим образом:

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