"ожидаемое первичное выражение перед '.' токен" в отладочном коде

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

#define DEBUG 1

#ifdef DEBUG
#define Serial.println(x) DEBUG_PRINT(x)
#else
#define DEBUG_PRINT(x)
#endif

И код в моей настройке void, в которой есть Serial.begin:

#ifdef DEBUG
Serial.begin(9600);
DEBUG_PRINT("Asteroid");
#endif

Что я делаю не так? Я чувствую, что это мой определяющий текст, но я не уверен.

Спасибо за ваше время. Гарден

, 👍0

Обсуждение

Макросы не могут содержать .. Таким образом, вы не можете определить макрос Serial.println(x). Вы, вероятно, все равно хотели определить это наоборот. #define DEBUG_PRINT(x) Serial.println(x), @Kwasmich

Я поменял их местами, согласно комментарию Квасмича. Теперь сообщение об ошибке «ожидается»; перед сериалом", @TheGaardenator

Где-то в вашем коде (не показанном выше) у вас есть оператор DEBUG_PRINT, где в предыдущей строке вы пропустили ;, @Kwasmich

Не знал, что это даст мне сообщение об ошибке в этой строке, если в строке ниже будет проблема. Спасибо!, @TheGaardenator

@Kwasmich Вы разместили ответ в качестве комментария. Пожалуйста, дайте правильный ответ. Тогда вы получите за это репутацию, и Stack Exchange рассмотрит вопрос как ответ. Выиграй, выиграй!, @Nick Gammon

@NickGammon, я вижу в этом типографскую ошибку (и я понизлю ответ на этот вопрос). я проголосовал за закрытие, @Juraj

@Juraj Опечатки тоже являются ошибками. Кроме того, это не опечатка. Типографской ошибкой будет Serial.print1n(). Это отсутствие понимания того, как макросы работают и должны формироваться со стороны ОП, и заслуживает помощи ОП в улучшении их понимания., @Majenko


2 ответа


1

Вы неправильно определили макрос препроцессора.
Думайте, что это похоже на оператор assign. Вы придумываете имя и что-то ему присваиваете.

#define SHORT_NAME(ARG) some_real_function_that_has_an_awkward_long_name(ARG)

Для справки см. руководство по вашему любимому компилятору GCC.
Всегда полезно делать это при использовании функций, которые вы раньше не использовали. Иногда это может быть поучительно.

,

2

Короче говоря, у вас есть макрос задом наперед.

Макросы формируются не как "Возьмите этот набор команд и назовите его X", а "Сделайте этот макрос X и приравняйте его к этому набору команд".

Где у вас есть:

#define Serial.println(x) DEBUG_PRINT(x)

вместо этого следует читать:

#define DEBUG_PRINT(x) Serial.println(x)

Поскольку макрос не содержит точки с запятой, когда вы ее вызываете, вам нужно указать точку с запятой, как если бы вы вызывали функцию:

DEBUG_PRINT("Aardvark");

Точку с запятой можно опустить, только если в макросе есть точка с запятой:

#define DEBUG_PRINT(x) Serial.println(x);

а затем:

DEBUG_PRINT("Aardvark")

Сделав это таким образом, ваш «пустой» макрос теперь становится действительно пустым при использовании. Без точки с запятой в макросе вам пришлось бы использовать:

DEBUG_PRINT("Aardvark");

Что для пустого варианта будет выглядеть так:

;

Не всегда желательно и может вызвать некоторые проблемы.

Поэтому, добавив точку с запятой в макрос, вы можете исключить ее из использования макроса, и ваш пустой вариант теперь выглядит следующим образом:

  
,