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

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

отладка.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 &e)
    {
        std::cout << e.GetMsg() << std::endl;
    }

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

    return result;
}

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

inc/debug.h:5:14: предупреждение: «LOGGER_DEBUG_MODE» определен, но не используется [-Wunused-variable] статическое логическое значение 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 &e)
    {
        std::cout << e.GetMsg() << std::endl;
    }

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

    return result;
}

Почему я получаю предупреждающее сообщение, даже если переменная LOGGER_DEBUG_MODE явно используется внутри оператора if? Я напутал что-то очевидное, что я не понимаю? Мои флаги компиляции для объектных файлов (где появляется предупреждение) g++ -Wall -Wextra -O1 -g -std=c++17 -save-temps=obj -Iinc -I/usr/local/include -c плюс 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;
}

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

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

Secundi 17.12.2020 13:41
#define _HDEBUG Это имя зарезервировано для языковой реализации. Определив его, ваша программа будет иметь неопределенное поведение. Вы должны использовать другое имя для вашего макроса.
eerorika 17.12.2020 14:23

@eerorika Поменяла на _HLOGGERDEBUG, спасибо!

Lucas Vaz 17.12.2020 14:27

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

eerorika 17.12.2020 14:33

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

Lucas Vaz 17.12.2020 14:36

@eerorika Я только что искал, почему вы просто не сказали, что любое имя, начинающееся с подчеркивания, за которым следует заглавная буква, зарезервировано?

Lucas Vaz 17.12.2020 14:41

@LucasVaz Я хотел, чтобы вы научились самостоятельно изучать языковые правила. Это ценный навык для программиста.

eerorika 17.12.2020 15:41
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
810
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

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

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

и т. д.

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

Lucas Vaz 17.12.2020 14:11

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

Mike Vine 17.12.2020 14:18
en.cppreference.com/w/cpp/keyword/static объясняет 3 различных использования статики - я забыл функцию локальной статики :-)
Mike Vine 17.12.2020 14:27

Другие вопросы по теме