Как можно отслеживать выполнение в C ++ без использования отладчика?

0

У меня есть простая C++ программа;

int someFunction()
{
    cout << "Testing here" << endl;
    cout << "reached here in function " << __LINE__ << " in " << __FUNCTION__ << endl; // debug purposes

    // do some more stuffs here

    cout << "reached here in function " << __LINE__ << " in " << __FUNCTION__ << endl; // debug purpsoes
}

Есть ли способ включения/выключения строк кодов, обозначенных как "цели отладки"? Идеи в случае проблем я могу просто написать один лайнер, чтобы включить такие коды отладки для отладки, и когда они решили отключить их.

Я знаю, что отладчики для этой цели, но хотят что-то простое для простых программ.

Теги:
c++11

4 ответа

3
Лучший ответ

Вы можете обернуть его в условное определение:

#ifndef NDEBUG
    // Debugcode here
#endif

Когда вы закончите отладку, просто определите NDEBUG во время компиляции. Вы также можете взглянуть на assert. Он управляется одним и тем же макросом NDEBUG и легко позволяет вам проверять условия в вашей программе. Вы также можете заставить его создавать значимые сообщения об ошибках:

assert(allWentWell && "Blah went wrong!");

Сообщение об ошибке assert также будет содержать информацию о том, где произошла ошибка.

3

В дополнение к другим ответам вы можете объявить глобальный флаг:

 #ifndef NDEBUG
 bool want_debug;
 #endif /*NDEBUG*/

затем определите макрос

 #ifndef NDEBUG
 #define DEBUG_OUT(Expr) do {if (want_debug)   \
    cout << __FILE__ << ":" << __LINE__ << " " \
         << Expr << endl;} while(0)
 #else
 #define DEBUG_Out(Expr) do{}while(0)
 #endif

и вы добавите множество заявлений, подобных

 DEBUG_OUT("here x="<< x);

Флаг want_debug может быть установлен во время выполнения (например, внутри отладчика или с некоторым аргументом программы -d обработанным вашим main). Если вы компилируете с помощью -dNDEBUG вы не получите никакого кода для операторов DEBUG_OUT.

Я использую NDEBUG препроцессора NDEBUG связанный со старым утверждением (3).

Конечно, будьте осторожны, чтобы избежать значимых побочных эффектов в DEBUG_OUT, например
DEBUG_OUT("here y=" << y++);/*WRONG side effect*/ DEBUG_OUT("here y=" << y++);/*WRONG side effect*/ это, безусловно, ошибка.

Если вы используете недавний компилятор GCC (например, g++ версия 4.9), вы также можете настроить его с помощью MELT, добавив волшебным образом (в своем расширении, закодированном в MELT), какой-нибудь пропуск, который автоматически добавит сообщения о регистрации (например, в конце каждой процедуры), Но это может означать недели работы (так что стоит больших проектов программного обеспечения).

  • 0
    @ Baile Starynkevitch, очень поучительно, спасибо.
3

Классический способ решить это - определить некоторые макросы регистрации; простым примером может быть:

#ifdef_NDEBUG
#    define LOG(X) 
#else
#    define LOG(X) do { std::clog<<__FILE__<<":"<<__LINE__<<" "<<(X)<<std::endl;} while(0)
#endif

Применение:

LOG("Before frobbing the widget (i="<<i<<")");

Конечно, это можно сделать на любой уровень сложности (существует множество библиотек, которые подходят к проблеме регистрации).

  • 0
    Очень похоже на мой ответ.
  • 0
    @BasileStarynkevitch: я заметил, и я проголосовал за ваш, так как он более полный.
0

Вы хотите "включить/выключить" часть кода, вы можете использовать макросы и директивы препроцессора #ifdef и #endif:

#ifdef _DEBUG
//run this code
#endif

Выше код будет работать, только если определена макрос _DEBUG:

#define _DEBUG
  • 2
    _DEBUG является зарезервированным идентификатором реализации и не должен использоваться в коде пользователя.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню