Скажем, у меня есть функция C++ debugPrint (int foo). Как я могу лучше всего снять это с релизов? Я не хочу окружать каждый вызов debugPrint с помощью #ifdefs, поскольку это было бы очень трудоемким. С другой стороны, я хочу быть на 100% уверенным, что компилятор передает все вызовы этой функции, а сама функция - из сборки релиза. Зачистка также должна произойти, если она вызывается с параметром, результатом которого является вызов функции. Например, debugPrint (getFoo()) ;. В этом случае я также хочу, чтобы вызов getFoo() был удален. Я понимаю, что функция inlining может быть опцией, но поддержка не гарантируется.Как удалить код отладки во время компиляции в C++?
ответ
Использование conditinal компиляции и макро:
#ifdef _DEBUG
#define LOG(x) debugPrint(x)
#else
#define LOG(x)
#endif
Определение _DEBUG
для отладочных и не определить его для построения релиза. Теперь в версии построить каждый
LOG(blahbhahblah);
будет расширен в пустую строку - даже параметры не будут оценены и не будет включен в излучаемом код.
Вы можете использовать любой уже существующий символ препроцессора, который определен в сборке отладки и не определен в версии вместо _DEBUG
.
Yep .. это именно то, что есть для макросов !! – Newtopian
Это опасно и подвержено ошибкам. 'int x = 0; LOG (x + = 2); use (x); 'будет вести себя иначе, если включен режим« release »или« отладка ». – LiraNuna
Да, будет. В этом мире нет ничего свободного. – sharptooth
Я сделал что-то подобное раньше с препроцессором.
#ifndef DEBUG
#define debugPrint
#endif
По существу, который удалит все отладочные строки
Err, не будет ли это верным 'debugPrintf («hello»); в довольно недействительный "(" привет "); ? – paxdiablo
@Pax, это совершенно верно. – strager
Но это может вызвать предупреждение. '(void) (" hello ")' представляется более подходящим. Это неправильно: debugPrint (GetFoo()) по-прежнему вызывает GetFoo() с этим макросом, который явно не требовался. – MSalters
сделать функцию инлайн, и внутри функции имеют # IfDef, как и это:
inline void debugPrint(whatever_t wtvr)
{
#ifdef DEBUG
Logger::log(wtvr);
#endif
}
Таким образом, оптимизатор будет обирать пустую функцию, сохраняя код чистым.
Будет ли это гарантировать, что параметр функции не будет оцениваться? – sharptooth
Это не поможет с другим требованием (что если код, который необходимо оценить для вычисления wtvr, также не будет сгенерирован) –
@sharptooth, они должны быть оценены с помощью этого решения. Однако, если оценка изменяет работу программы (то есть побочные эффекты), проблема в том, что вызовы функции регистратора могут делать больше, чем просто протоколирование. – strager
#ifdef _DEBUG
#define debugPrint(x) _debugPrint(x)
void _debugPrint(int foo) {
// debugPrint implementation
}
#else
#define debugPrint(x)
#endif
@ ответ sharptooth хороший. Одно небольшое изменение, которое я обычно делаю, однако, чтобы отключить отладку, если NDEBUG
макроса не определен, а не если отладочный макрос определяются:
#ifndef NDEBUG
#define LOG(x) debugPrint(x)
#else
#define LOG(x)
#endif
Когда NDEBUG
макроса определен, то C assert
s, которые я предпочитаю использовать довольно либерально для утверждения таких вещей, как предпосылки и постусловия, или даже для разъяснения результата сложной логики, также отказаться от компиляции. Это стандартный макрос для «без отладки». И макрос NDEBUG
уже должен быть определен в сборках релизов.
См: http://www.opengroup.org/onlinepubs/009695399/functions/assert.html
- 1. Как ввести код C# во время компиляции?
- 2. C++: устранить этот код во время компиляции?
- 3. Код запуска во время компиляции
- 4. Ошибки при отладке во время компиляции во время компиляции
- 5. IntelliJ - Выберите исходный код во время отладки
- 6. Исключить код отладки JavaScript во время минимизации
- 7. C++: Как создать константу во время компиляции?
- 8. Как выполнить препроцессор C во время компиляции?
- 9. Ресурс релиза во время отладки (C++, MSVC)
- 10. Run Nim код во время компиляции
- 11. Как вывести код во время отладки в Visual Basic 2010?
- 12. Почему ниже C код не во время компиляции
- 13. Не удается войти в ссылочный код сборки во время отладки
- 14. значения параметров отладки во время выполнения C#
- 15. offsetof во время компиляции
- 16. C++ строки перехода во время отладки
- 17. Откуда возникает код asm во время процесса отладки в GDB?
- 18. Память C++, выделенная во время компиляции
- 19. Темы во время отладки
- 20. Как выбрать макросы во время компиляции?
- 21. Получить данные из во время компиляции C#
- 22. C макро оценить во время компиляции
- 23. Что происходит во время компиляции Objective-C
- 24. Проверка выравнивания массива C во время компиляции
- 25. Как удалить некоторый javascript во время компиляции grunt-usemin
- 26. Как настроить код VS для компиляции/отладки C++?
- 27. Обнаружить версию C# во время компиляции
- 28. Функция C++ не найдена во время компиляции
- 29. Как изменить код во время компиляции на основе флага в C#
- 30. Как условно удалить часть моего приложения во время компиляции/запуска?
Единственный способ избавиться от 'getFoo()' в 'DebugPrint (getFoo())' является использование макросов. Но это приведет к тому, что программа будет вести себя по-разному при отладке и в настройках выпуска. Это действительно опасно. –
Это опасно, если getFoo() имеет некоторую скрытую логику, отличную от значения переменной foo. Но это плохое кодирование. – juvenis