#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 различных использования статики — я забыл функцию локальной статики 🙂