Использование числовой константы в макрофункции

#c #macros #c-preprocessor #avr

#c #макросы #c-препроцессор #avr

Вопрос:

Я пишу простую библиотеку для своего AVR, и я хотел попробовать использовать макрофункцию для определения моей скорости передачи данных. Многие функции в библиотеке AVR используют макрос F_CPU, а также тот, который я хочу написать.

Вот что у меня есть для определения макроса и моей предполагаемой реализации:

 #define BAUD_SELECT(baud) ((F_CPU)/(2*baud)-1)

myubrr = BAUD_SELECT(38400);
  

Я пытался использовать #define F_CPU 800000000UL, а также в файле make как -D»F_CPU 800000000UL», но я всегда получаю одну и ту же ошибку в строке реализации.

 expected ')' before numeric constant
  

Я уверен, что это как-то связано с моим злоупотреблением #define, и что определение макроса находится в заголовочном файле, реализация — в соответствующем файле .c, а определение F_CPU либо в файле makefile, либо в другом основном файле .c.

РЕДАКТИРОВАТЬ Я изменил скобки, как было предложено, и запустил препроцессор и нашел выходной файл (по крайней мере, я думаю)

  unsigned int myubrr = ((8000000UL 1)/(2*(baud))-1);
  

Он помещает дополнительный 1 там, где должен быть F_CPU, у меня нет опыта работы с препроцессором, поэтому я не уверен, как заставить его этого не делать, но, возможно, в этом проблема?

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

1. попробуйте запустить на нем препроцессор и посмотреть, к чему он расширяется

2. Это кажется правильным. Вам наверняка не хватает круглой скобки где-то еще. Кстати, в выражении макроса всегда помещайте переменные, принятые в качестве аргумента, в круглые скобки. Представьте, что ваш макрос называется like BAUD_SELECT(some_baud 100) ((F_CPU)/(2*some_baud 100)-1) , который будет расширяться, а это не то, что вы хотите. Итак, вам нужно будет написать выражение следующим образом: ((F_CPU)/(2*(baud))-1)

3. Присмотритесь повнимательнее к определению F_CPU … возможно, в конце строки за пределами окна вашего редактора есть какой-то мусор.

Ответ №1:

Попробуйте заключить ее в круглые скобки:

 #define BAUD_SELECT(baud) ((F_CPU)/(2*(baud))-1)
  

Ответ №2:

Для меня это работает нормально:

 #define BAUD_SELECT(baud) ((F_CPU)/(2*(baud))-1)

unsigned int myubrr = BAUD_SELECT(38400);
  

когда я компилирую с

 $ cc -c -DF_CPU=8000000UL t.c
  

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

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

1. Как ни странно, переход от -D»F_CPU 800000000UL» к -D»F_CPU=800000000UL» позволил ему скомпилироваться, я никогда не замечал никакого различия между ними до сих пор, но все еще не уверен, что препроцессор делает по-другому.

2. Действительно, это как-то странно… 😉 — При первом запуске -D «F_CPU 800000000UL» определяет один макрос с пробелом в его идентификаторе, а именно макрос ‘F_CPU 800000000UL’, поскольку знак ‘=’ не используется, он получает значение 1. Итак, у нас есть ‘F_CPU 800000000UL 1’. Затем при разборе вашего кода препроцессор принимает эту фразу как есть и заменяет ‘F_CPU’ в вашем коде на ‘800000000UL 1’. Можно рассматривать это как ошибку cpp? ;->