Предупреждение о неиспользуемой переменной даже при явном ее использовании внутри оператора IF

#c #gcc #g #c 17

#c #gcc #g #c 17

Вопрос:

Я пытаюсь создать (используя C 17) простой заголовок отладки, который выполняет только некоторые строки кода, если включен флаг LOGGER_DEBUG_MODE. Так определяется мой заголовок (я также пытался использовать { x; } вместо x, но предупреждение сохраняется):

debug.h

 #ifndef _HDEBUG

    #define _HDEBUG

    static bool LOGGER_DEBUG_MODE = true;
    #define R_DEBUG(x) if(LOGGER_DEBUG_MODE == true) x
    
#endif
 

Я включил debug.h и в какой-то момент моего кода я вызываю макрофункцию R_DEBUG для печати некоторых значений:

logger_adc.cpp

 double anlg_device_t::eval_formula()
{
    double result = -9999;

    try
    {
        result = parser.Eval();
    }
    catch (mu::Parser::exception_type amp;e)
    {
        std::cout << e.GetMsg() << std::endl;
    }

    R_DEBUG(std::cout << "Eval Result: " << result << std::endl);

    return resu<
}
 

Я ожидал, что все будет работать правильно, но когда я запускаю makefile, я получаю это предупреждение:

inc/debug.h:5:14: предупреждение: ‘LOGGER_DEBUG_MODE’ определен, но не используется [-Wunused-variable] статический bool LOGGER_DEBUG_MODE = true;

Я думал, что мое определение было перепутано, но после проверки временных файлов, созданных g , оказывается, что препроцессор сделал все так, как я ожидал:

logger_adc.ii

 double anlg_device_t::eval_formula()
{
    double result = -9999;

    try
    {
        result = parser.Eval();
    }
    catch (mu::Parser::exception_type amp;e)
    {
        std::cout << e.GetMsg() << std::endl;
    }

    if(LOGGER_DEBUG_MODE == true) std::cout << "Eval Result: " << result << std::endl;

    return resu<
}
 

Почему я получаю предупреждающее сообщение, даже если переменная LOGGER_DEBUG_MODE явно используется внутри оператора if? Я что-то напутал очевидное, что я не улавливаю? Мои флаги компиляции для объектных файлов (где возникает предупреждение) равны g -Wall -Wextra -O1 -g -std=c 17 -save-temps=obj -Iinc -I/usr/local/include -c plus pkg-config --cflags --libs libmodbus

При необходимости это моя основная функция:

main.cpp

 #include "logger_adc.h"

int main()
{
    anlg_device_t test (ADC_CHIP_1, 1, 18, 1, 1, true);
    test.set_formula("2*x","x", test.get_voltage_ptr());

    std::cout << "Test Voltage: " << test.get_voltage() << std::endl << "Test Relative: " << test.get_relative() << std::endl;

    std::cout << "Test Formula (2*x): " << test.eval_formula() << std::endl;


    return 0;
}
 

Заранее спасибо!

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

1. В качестве общего намека, связанного с вашей проблемой: не пытайтесь создавать потоки управления с помощью статических (const) переменных, если это возможно. Если требуется переключатель времени компиляции (что, похоже, здесь действительно так), используйте здесь только схемы времени компиляции, если это возможно (#ifdefs или constexpr начиная с C 17).

2. #define _HDEBUG Это имя зарезервировано для языковой реализации. Определяя ее, ваша программа будет иметь неопределенное поведение. Вы должны использовать другое имя для своего макроса.

3. @eerorika изменил его на _HLOGGERDEBUG , спасибо!

4. @LucasVaz Это имя также зарезервировано. Вы должны выбрать другой.

5. @eerorika zzzzzz, изменил его на _HDATALOGGERSIGMADEBUG . Если это зарезервировано, я сдаюсь.

Ответ №1:

У вас есть заголовок, который определяет a static bool LOGGER_DEBUG_MODE =true; . Если вы включите этот заголовок в несколько файлов C , то каждый файл получит свою собственную копию этого bool.

В вашем main.cpp вы не используете R_DEBUG , поэтому копия этого bool (которая, предположительно, поступает из including logger_adc.h ) действительно не используется в этом файле.

Возможные решения:

Вы должны сделать так, чтобы у вас была только одна копия этого bool (объявите его в заголовке с extern помощью и определите его в одном файле C .

Используйте определения сборки вместо проверок во время выполнения

и т. д

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

1. Я думал, что статические переменные уже разделены между объектами, что многое объясняет. Значит, это станет чем-то вроде extern bool LOGGER_DEBUG_MODE; в заголовке и bool LOGGER_DEBUG_MODE = true; в основном (например)?

2. Static — это перегруженный термин в C . В классе static переменная действительно является общей для всех экземпляров этого класса. Как глобальная переменная static означает, что она локальна для этого файла C (технически единица перевода )

3. en.cppreference.com/w/cpp/keyword/static объясняет 3 различных использования статики — я забыл функцию локальной статики 🙂