РЕДАКТИРОВАТЬ: код, помеченный как «не работает» на самом деле работает. Это было из-за синтаксических проблем в моих тестах, не обнаруженных компилятором. Так что вопрос уже решен, спасибо.
C ++ не является языком, которым я пользуюсь каждый день, поэтому возможно, что решение тривиально.
Сначала о контексте. Я использую C ++ для разработки на микроконтроллере (на базе Arduino, AVR microcontroller ), поэтому я не использую STL , printf-подобные функции, следует избегать new / malloc и C ++ тоже.
У меня есть объект с именем Serial
, похожий на Cost ioutream C ++, для связи с микроконтроллером через последовательный интерфейс. Я перегружен оператор «<<» класса, из которого <code>Serial является экземпляром, поэтому я могу сделать что-то вроде этого:
Serial << "debug " << "value is " << 3 << endl;
// Whithout the << operator it would be:
Serial.print("debug ");
Serial.print("value is ");
Serial.println(3);
Я хотел бы создать функцию (или макрос), которая разрешает этот тип строки, только если включена отладка, и которая автоматически добавляет строку «отладка» и добавляет значение «endl» в конце.
Так что-то в этом роде (предупреждение, код не работает, потому что «данные» не могут раскрываться как целая инструкция C ++):
#ifdef DEBUG
#define PRINT_DEBUG(data) do {Serial << "debug " << data << endl;} while(0)
#else
#define PRINT_DEBUG(data) do {} while(0)
#endif
// This code works
PRINT_DEBUG("hello world");
// This code does not work
int value1 = 3;
char * value2 = "this is a string";
PRINT_DEBUG("sensor1 value:" << value1 << " other sensor value " << value2);
Этот тип функции / макроса позволил бы мне легко выводить строки на моем последовательном интерфейсе с определенным «строковым протоколом» без необходимости повторять строку «отладки» в начале. Это также позволило бы мне легко отключить печать сообщения отладки, не устанавливая макрос DEBUG. У меня также есть только один "#ifdef DEBUG" вместо нескольких в моем коде.
Мне удалось сделать что-то подобное с переменными аргументами , но я ненавижу это решение, потому что его опасно использовать (я не хочу указывать количество аргументов), и я не могу смешивать разные типы данных:
void __rawSend(char * args, ...) {
Serial.print(args);
va_list paramList;
va_start (paramList, args);
while(true) {
char * next = va_arg(paramList, char*);
if (next == NULL) {
break;
}
Serial.print(" ");
Serial.print(next);
}
Serial.println();
va_end(paramList);
}
#ifdef DEBUG
#define printDebug(...) do {__rawSend(OUTPUT_DEBUG, __VA_ARGS__, NULL);} while(0)
#else
#define printDebug(...) do {} while(0)
#endif
int intValue = 1;
char * stringValue = "data";
// This works
printDebug("hello",stringValue);
// This does not works
printDebug("data is", intValue);
Как я могу это сделать? Возможно ли это с помощью макросов (избегая вариационных аргументов и смешивая разные типы)? Есть ли лучшее решение?