Определение раздела кода, в котором выполняется другой путь кода - PullRequest
0 голосов
/ 29 июня 2018

Можно ли определить раздел или область действия в моем коде, в котором выполняется другой путь кода, без использования глобальной или передаваемой вниз переменной состояния ?

В целях отладки я хочу иметь возможность заключить раздел неисправного кода в область действия или #define, чтобы временно включить предопределенное поведение отладки в этом разделе, например, использовать отладочные данные, более точный тип данных, уже проверенный алгоритм ... Это должно работать в многопоточном приложении, в котором несколько потоков, вероятно, одновременно выполнят один и тот же общий код, но только некоторые из них вызвали этот код изнутри. определенный раздел.

Например, вот некоторый псевдокод, который не работает, но может проиллюстрировать, что я хотел бы сделать. Статическая дорогая функция, которая вызывается из нескольких мест одновременно:

Result Algorithms::foo()
{
#ifdef DEBUG_SECTION
    return Algorithms::algorithmPrecise(dataPrecise);
#else
    return Algorithms::algorithmOptimized(dataOptimized);
#endif
}

Три класса, экземпляры которых необходимо часто обновлять:

Result A::update()
{
    return Algorithms::foo();
}

Result B::update()
{
    Result result;

#define DEBUG_SECTION
        ...

        result = a.update() + 1337;

        ...
#undef DEBUG_SECTION

    return result;
}

Result C::update()
{
    return a.update();
}

Как видите, класс A напрямую вызывает foo(), тогда как в классе B, foo() вызывается косвенно, вызывая a.update() и некоторые другие вещи. Допустим, B::update() возвращает неправильный результат, поэтому я хочу иметь возможность использовать реализацию отладки foo() только из этого места. В C::update() оптимизированная версия все еще должна использоваться.

Моя концептуальная идея состоит в том, чтобы определить DEBUG_SECTION вокруг неисправного кода, который будет использовать реализацию отладки в этом месте. Это, однако, на практике не работает, так как Algorithms::foo() компилируется один раз, а DEBUG_SECTION не определяется. В моем приложении Algorithms, A, B и C расположены в отдельных библиотеках.

Я хочу, чтобы внутри секции, определенной в коде, выполнялась другая секция кода в общем коде. Однако за пределами этого раздела я все еще хочу выполнить исходный код, который во время выполнения будет происходить одновременно, поэтому я не могу просто использовать переменную состояния. Я мог бы добавить параметр debugFlag к каждому вызову в DEBUG_SECTION, который передается в каждом рекурсивном вызове, который затем передается в Algorithms::foo(), но это чрезвычайно подвержено ошибкам (вы не должны пропустить ни одного вызова, но раздел может быть довольно большим, распределенным по разным файлам,…) и довольно грязным в большой системе Есть ли лучший способ сделать это?

Мне нужно решение для C ++ 11 и MSVC.

1 Ответ

0 голосов
/ 11 июля 2018

Это может работать с использованием шаблона:

template<bool pDebug>
Result Algorithms::foo()
{
    if(pDebug)
        return Algorithms::algorithmPrecise(dataPrecise);
    else
        return Algorithms::algorithmOptimized(dataOptimized);
}

С другой стороны, это означает перемещение определения вашей функции в заголовок (или принудительное создание шаблона, см. эти ответы ).

Недостатком является то, что изменение вызова Algorithms :: foo () с instance.foo<false> на instance.foo<true> каждый раз, когда вы хотите переключиться между отладкой и выпуском, может потребовать усилий. Если у вас есть несколько затронутых вызовов, вы можете использовать константную переменную времени компиляции, чтобы уменьшить усилия при наборе текста, но не зная ваш код точно, я не могу оценить, является ли это возможным решением.

Если большая часть вашего кода использует оптимизированную версию функции, вы также можете установить для параметра шаблона значение по умолчанию false (template<bool pDebug = false>), чтобы избежать изменения существующего кода, который не вызовет версию отладки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...