Миландр
http://forum.milandr.ru/

Почему не работает макрос?
http://forum.milandr.ru/viewtopic.php?f=27&t=2463
Страница 1 из 1

Автор:  stranderer [ 2015-мар-20 12:30 ]
Заголовок сообщения:  Почему не работает макрос?

Возможно, что я плохо знаю С, но...
Работаю в ФИТОН-овском CodeMasterARM, разрабатываю ПО для 1986ВЕ91Т. Определяю в проекте макрос pBitSet для установки или очистки бита в порту микроконтроллера. Он реализуется по-разному в зависимости от того, использую ли я Bit-Band регион для доступа к отдельным битам или нет.
Затем через этот макрос определяю макросы pBitPls (для выдачи максимально короткого импульса в заданном разряде порта) и pBitWait (для выдачи в заданном разряде импульса, длительность которого определяется выполнением заданного условия).
Всё это лежит в модуле DeclMCU.h
Теперь если в модуле Select.h идентификатор BITBAND_ACCESS определён, то всё работает нормально, если же не определён, то макрос pBitSet работает, а макросы pBitPls и pBitWait вызывают сообщение "Syntax error". Почему?
Если я в С-модулях вместо этих макросов расписываю всё то же самое через макрос pBitSet, то всё работает. Я было предположил, что есть ограничение на длину строки на выходе препроцессора и разбил проблемные макросы на несколько строк, но это не помогло.
В чём тут может быть дело?

Вложения:
Project01.zip [12.53 КБ]
Скачиваний: 167

Автор:  prostoRoman [ 2015-мар-20 13:59 ]
Заголовок сообщения:  Re: Почему не работает макрос?

stranderer писал(а):
Возможно, что я плохо знаю С, но...

хорошо знаете. Попробуйте добавить точку с запятой (;) в сроках макросов.
Код:
#ifdef BITBAND_ACCESS
#define pBitSet(name,val) *name = ((val)&1)
#define pBitNeg(name)     *name ^= 1
#define pBitGet(name)     (*name)
#else
#define pBitSet(name,val) name->RXTX = ((val)&1)? name->RXTX|(1<<name##_b) : name->RXTX&(~(1<<name##_b))  ; // основные проблемы, вероятно, тут
#define pBitNeg(name)     name->RXTX ^= (1<<name##_b)
#define pBitGet(name)     ((name->RXTX>>name##_b)&1)
#endif // #ifdef BITBAND_ACCESS#define pBitPls(name,val) pBitSet(name,val);\
                          pBitSet(name,(val)^1)
#define pBitTgl(name) pBitNeg(name);\
                      pBitNeg(name); //тут..
#define pBitWait(cnd,name,val) while (cnd)\
                               {pBitSet(name,val);}\
                               pBitSet(name,(val)^1); //там...


И вообще, ; не проблема, можно лепить сколько душе угодно.

Автор:  stranderer [ 2015-апр-15 17:33 ]
Заголовок сообщения:  Re: Почему не работает макрос?

Попробовал. Как и ожидал, не помогло. :( Пока работаю только через Bit-band Area, там никаких проблем...

Автор:  ASavit [ 2015-апр-17 15:07 ]
Заголовок сообщения:  Re: Почему не работает макрос?

В опциях компилятора включите генерацию выходного файла препроцессора и посмотрите, какой код получается в результате препроцессирования.

Автор:  stranderer [ 2015-апр-17 19:26 ]
Заголовок сообщения:  Re: Почему не работает макрос?

А никакой не получается! Ну, то есть в файле препроцессора эта строка уже не появляется :(

Автор:  ASavit [ 2015-апр-20 14:27 ]
Заголовок сообщения:  Re: Почему не работает макрос?

Вот, что ответили разработчики компилятора:

В примере, в теле макроса pBitWait используется вызов макроса pBitSet, в который передаются параметры name и val. В соответствии с правилами фазы препроцессирования языка С (см. С Стандарт п.6.8.3), в процессе макроподстановки (при вызове макроса pBitWait) производится сначала замена имен параметров макросов на их значения, а уже затем подстановка тела макроса pBitSet. Таким образом, при подстановке тела макроса pBitSet, значением параметра name в данном случае является не токен o_IndFun, а ((MDR_PORT_TypeDef *)(0x400C0000)). В результате, при выполнении оператора ## в теле макроса pBitSet, получается последовательность символов ((MDR_PORT_TypeDef *)(0x400C0000))_b которая не является валидным токеном фазы препроцессирования.

Автор:  stranderer [ 2015-апр-20 22:43 ]
Заголовок сообщения:  Re: Почему не работает макрос?

Спасибо! Теперь понятно, буду переделывать...

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/