Удаление кода в режиме выпуска с помощью макросов C

#c #debugging #visual-studio-debugging

Вопрос:

У меня есть некоторый код, который используется для отладки, и я не хочу, чтобы он был в выпусках.
Могу ли я использовать macros их для комментариев?
Например:

 #include <iostream>

#define p(OwO) std::cout << OwO
#define DEBUG 1    // <---- set this to -1 in release mode

#if DEBUG == 1
#define DBUGstart
#define DBUGend
// ^ is empty when in release mode
#else
#define DBUGstart /*
#define DBUGend    */
/*
IDE(and every other text editor, including Stack overflow) comments the above piece of code,
problem with testing this is my project takes a long
time to build
*/
#endif

int main() {
    DBUGstart;
    p("<--------------DEBUG------------->n");
    // basically commenting this line in release mode, therefore, removing it
    p("DEBUG 2n");
    p("DEBUG 3n");
    DBUGend;
    p("Hewwo Worldn");
    return 0x45;
}
 

Для однострочных отладок я мог бы легко сделать что-то вроде:

 #include <iostream>

#define DEBUG -1  // in release mode
#define p(OwO) std::cout << OwO

#if DEBUG == 1
#define DB(line) line
#else
#define DB(line)
#endif

int main()
{
    DB(p("Debugn"));
    p("Hewwo World");
    return 0x45;
}
 

Но я думаю, что это будет немного запутанно с несколькими строками

Я работаю с MSVC (Visual Studio 2019), если это не работает, то есть ли какой-либо другой способ реализовать то же самое (для нескольких строк это довольно просто для отдельных строк)?

Комментарии:

1. Да, вы можете использовать макросы для (эффективного) комментирования кода, например, путем переноса в #ifdef / #endif , чтобы разрешить код, если определен макрос (или #ifndef / #endif разрешить код, если макрос НЕ определен). Возможно, вы захотите рассмотреть NDEBUG в качестве имени макроса, поскольку оно фактически используется в стандарте для управления использованием assert() — это функция, часто используемая в целях отладки (обратите внимание, что это NDEBUG означает «не отладка», поэтому включает функциональность assert() , если она НЕ определена).

2. NDEBUG это не очень хороший выбор, потому что он используется для управления assert() макрокомандой, а файл заголовка намеренно не является идемпотентным . Это означает, что вы можете управлять поведением макроса, определяя или отменяя определение NDEBUG макроса и включая <cassert> его снова. Даже в сборках выпуска, обычно для одноразовых диагностических сборок.

Ответ №1:

Ты делаешь это излишне сложным.

Вместо того, чтобы условно вставлять комментарии в стиле C, если они выпущены, просто вставьте код, если он отлажен. Visual Studio определяет _DEBUG по умолчанию в конфигурациях отладки, поэтому это можно использовать следующим образом:

 #include <iostream>

int main() {

    std::cout << "hello there.n";

#ifdef _DEBUG
    std::cout << "this is a debug build.n";
#endif

}
 

Комментарии:

1. Фу-у-у, мне это не нравится. Наличие автоматической отладки/выпуска в MSVC, но необходимость настройки вручную для других компиляторов вызывает проблемы.

2. это не автоматическая работа. он просто установлен в разделе препроцессора настроек проекта для конфигураций отладки по умолчанию, но может быть удален и т.д. но да, если кросс-платформенная проблема, было бы лучше определить свой собственный и установить его в своем инструменте кросс-платформенной сборки. лично у меня нет проблем с использованием препроцессора здесь, хотя; это похоже на последнее, для чего препроцессор все еще хорош.

Ответ №2:

Для этого вам даже не нужны макросы. Условная компиляция встроена прямо в язык:

 #include <iostream>

constexpr bool gDebug = true;

int foo();

int main() {

    std::cout << "hello there.n";

    int foo_res = foo();

    if constexpr (gDebug) {
       std::cout << "Foo returned: " << foo_res << "n";
    }
}
 

Это имеет непосредственное преимущество в том, что вы по-прежнему проверяете, что код действителен, даже когда он скомпилирован.

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