реклама на сайте
подробности

 
 
> Вызов «xcat(xcat(1, 2), 3)» будет заменён на «123», не хватает мозга понять!
ViKo
сообщение Apr 7 2018, 19:41
Сообщение #1


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Что в книге Кернигана с Ричи, что на просторах интернет говорится о том что во вложенных макросах надо объединять строки в два этапа:
#define cat(x,y) x##y
#define xcat(x,y) cat(x,y)
и тогда уже будет нормально выполняться
xcat(xcat(1,2),3)
Как пройти по шагам, что при этом будет выполняться?
В Википедии бред какой-то наблюдаю. Также и во многих интернетных статьях.
https://ru.wikipedia.org/wiki/%D0%9F%D1%80%...80_%D0%A1%D0%B8
http://we.easyelectronics.ru/Soft/preprocessor-c.html
https://www.opennet.ru/docs/RUS/cpp/cpp-5.html
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Arlleex
сообщение May 4 2018, 16:36
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Код
потому что каждый раз макросы разворачиваются до конца своей вложенности.

Вот. Это и есть ключ к ответу на мой вопрос laughing.gif

А насчет всех макросов, то вот:
Код
#define PERIPH_BASE 0x40000000
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
#define SPI1_BASE (APB2PERIPH_BASE + 0x3000)
#define SPI1 ((SPI_TypeDef *)SPI1_BASE)

#define GPIO_AF_SPI1 ((uint8_t)0x05)

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

Код
// HW_ADCBank1Init - функция инициализации периферии для работы с внешними АЦП.
// Параметры: нет.
// Возвращаемое значение: нет.
static void HW_ADCBank1Init(void)
{
  #define LCD_SPI_MODULE SPI1
  #define GPIO_AF_EXPAND_E(a, b) a##b
  #define GPIO_AF_EXPAND(a, b) GPIO_AF_EXPAND_E(a, b)

  GPIO_PinAFConfig(GPIO_ADC_SPI1_SCK.GPIO,  GPIO_ADC_SPI1_SCK.PinSource,  GPIO_AF_EXPAND(GPIO_AF_, LCD_SPI_MODULE));
  GPIO_PinAFConfig(GPIO_ADC_SPI1_MISO.GPIO, GPIO_ADC_SPI1_MISO.PinSource, GPIO_AF_SPI1); // GPIO_AF_SPI1 я пытаюсь получить и в предыдущей строке
  ...
  ...
  ...

выдает в консоли:
Код
User\Hardware.c(449): warning:  #223-D: function "GPIO_AF_" declared implicitly

Стоит переписать как
Код
#define #define LCD_SPI_MODULE _SPI1
...
GPIO_PinAFConfig(GPIO_ADC_SPI1_SCK.GPIO,  GPIO_ADC_SPI1_SCK.PinSource,  GPIO_AF_EXPAND(GPIO_AF, LCD_SPI_MODULE));

то все работает и преобразуется во что нужно.
Однако жутко неудобен этот "хвост" в виде нижнего подчеркивания... Ведь в коде хотелось бы иметь
Код
SPI_Cmd(LCD_SPI_MODULE, ENABLE);

а не
Код
SPI_Cmd(SPI1, ENABLE);

Есть конечно решение "в лоб", это сделать несколько определений:
Код
#define LCD_SPI_MODULE SPI1
#define _LCD_SPI_MODULE_ _SPI1

и использовать первый, где требуется именно имя SPI1, а второй - там где этот кусок текста слепляется с другими макросами, например, в имени GPIO_AF_SPI1.

P.S. Уважаемые, а можно ли в тегах [код] раскрашивать текст в разный цвет? А то хотелось бы акцентировать внимание на что-то, да не получается.

Сообщение отредактировал Arlleex - May 4 2018, 16:50
Go to the top of the page
 
+Quote Post
Baser
сообщение May 4 2018, 18:23
Сообщение #3


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(Arlleex @ May 4 2018, 19:36) *
function "GPIO_AF_" declared implicitly

Понял, почему у вас ругается на функцию: дефайн на SPI1 заключен в скобки, поэтому на выходе получается
GPIO_AF_((uint32_t*)((0x40000000 + 0x00010000) + 0x3000))
что имеет синтаксис функции.

Цитата
Есть конечно решение "в лоб", это сделать несколько определений:
и использовать первый, где требуется именно имя SPI1, а второй - там где этот кусок текста слепляется с другими макросами, например, в имени GPIO_AF_SPI1.

Похоже это единственный способ, ибо вы хотите одним выстрелом убить двух зайцев, а препроцессор Си это не умеет sm.gif

Вы хотите применить лексему SPI1, которая уже определена как вложенный макрос, еще и как простой текст для подстановки.
А у препроцессора нет средств для указания ему как эту лексему обрабатывать в каждом случае.

Цитата
P.S. Уважаемые, а можно ли в тегах [код] раскрашивать текст в разный цвет? А то хотелось бы акцентировать внимание на что-то, да не получается.

В коде нельзя, в цитате можно, но в цитате все пробелы сокращаются до единственного.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ViKo   Вызов «xcat(xcat(1, 2), 3)» будет заменён на «123»   Apr 7 2018, 19:41
- - jcxz   Цитата(ViKo @ Apr 7 2018, 22:41) Как прой...   Apr 7 2018, 19:47
|- - ViKo   Цитата(jcxz @ Apr 7 2018, 22:47) В свойст...   Apr 7 2018, 19:52
|- - AHTOXA   Eclipse показывает 4 шага: Кодxcat(cat(1,...   Apr 7 2018, 20:01
- - ViKo   То есть, сначала в аргументе макрофункции произошл...   Apr 7 2018, 20:18
- - ViKo   Точнее, вопрос, почему в макрофункции cat(cat(1,2)...   Apr 8 2018, 05:19
|- - SSerge   Цитата(ViKo @ Apr 8 2018, 12:19) Точнее, ...   Apr 8 2018, 10:31
|- - AHTOXA   Цитата(ViKo @ Apr 8 2018, 10:19) Точнее, ...   Apr 8 2018, 10:33
- - ViKo   Ага, так в выражении: Если в замещающей последоват...   Apr 9 2018, 09:40
- - Baser   Если есть желание совсем "надломить моск...   Apr 9 2018, 09:54
- - ViKo   Спасибо, почитаем-с! Я, в принципе, пользуюсь ...   Apr 9 2018, 10:01
- - XVR   Можно проще - # и ## применяются ДО ТОГО, как прои...   Apr 9 2018, 11:02
- - Arlleex   В общем это тема для меня пока что не совсем понят...   May 4 2018, 07:50
|- - Baser   Цитата(Arlleex @ May 4 2018, 10:50) Это в...   May 4 2018, 13:42
- - Arlleex   Ну да, получается, что так. Спасибо   May 4 2018, 18:25


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 04:06
Рейтинг@Mail.ru


Страница сгенерированна за 0.01363 секунд с 7
ELECTRONIX ©2004-2016