Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83

Удаление токена из макроса. Возможно ли?

21.06.2025, 16:05. Показов 5703. Ответов 34
Метки нет (Все метки)

Всем привет.

В си есть оператор для вставки токена в макрос для определения нового макроса:
C++
1
#define summa(x, y, z) (num##x + num##y + num##z)
Допустим имеем вот такие константы:
C++
1
2
3
#define num1  12
#define num2  25
#define num3  38
и при использовании этого макроса:
C++
1
int value = summa (1, 2, 3);
Получаем значение 75. Всё хорошо, всё работает.

Но возможно ли не вставлять, а наоборот, удалять токен из макроса???

Нужно чтобы при вызове макроса добавлялся другой макрос по маске. т. е. если я использую аргумент num1, то из этого аргумента нужно убрать последний токен (или несколько), а затем к нему нужно добавить заданный токен. Чтобы получилась вот такая упрощённая конструкция:
C++
1
2
int value1 = summa (num1);
int value2 = summa (num2);
А по факту должно быть так:
C++
1
2
int value1 = num1 + num3;
int value2 = num2 + num3;
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.06.2025, 16:05
Ответы с готовыми решениями:

Получение токена (OAuth 2.0) Qt 5.3
Подскажите, что нужно использовать для работы с протоколом OAuth 2.0? QNetworkAccessManager? Если...

Функция токенизирования строк
Помогите пожалуйста. Ниже приведён рабочий код на Visual C, мне его нужно переделать под Builder. ...

токены
здравствуйте! нужны идеи по решению этой задачи. у меня никаких кроме как поделить их на токены......

34
фрилансер
 Аватар для Алексей1153
6489 / 5717 / 1133
Регистрация: 11.10.2019
Сообщений: 15,261
22.06.2025, 08:02
Mr McLaren, вместо макросов сделай функции. Макросами лучше не пользоваться.
0
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83
22.06.2025, 11:17  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
вместо макросов сделай функции
Только под дулом автомата.

тем более что функция всё равно не решает вопрос. И есть даже библиотечные функции. Вы невнимательно читали.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
Макросами лучше не пользоваться
А то что?

Да, я и сам не люблю изобилие макросов, но если применение оправдано, то от них только польза.
0
фрилансер
 Аватар для Алексей1153
6489 / 5717 / 1133
Регистрация: 11.10.2019
Сообщений: 15,261
22.06.2025, 11:40
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Только под дулом автомата.
почему?

Цитата Сообщение от Mr McLaren Посмотреть сообщение
А то что?
макросы - это плохо. Функции ничем не хуже, но их проще и безопаснее писать, отлаживать и использовать

Цитата Сообщение от Mr McLaren Посмотреть сообщение
тем более что функция всё равно не решает вопрос
я, если честно, не совсем понял проблему. Сейчас попробую снова прочитать
0
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83
22.06.2025, 11:59  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
почему?
Ответ очень прост: Быстродействие. А когда речь идёт о работе с пинами МК - этот аспект может стать критически важным.
Функция требует дополнительных операций: пропись аргументов, вызов функции, обработку данных, выполнение требуемой операции. А макрос использует только последнее и воздействует непосредственно на регистры. Что в несколько раз повышает быстродействие пина.

Добавлено через 4 минуты
Цитата Сообщение от Алексей1153 Посмотреть сообщение
макросы - это плохо.
Некоторых программистов послушает - так для них всё плохо. Есть многие кто с пеной во рту будет утверждать что goto зло.
Кто-то switch не любит...
Всё хорошо, если пользоваться с умом.
0
фрилансер
 Аватар для Алексей1153
6489 / 5717 / 1133
Регистрация: 11.10.2019
Сообщений: 15,261
22.06.2025, 12:05
Mr McLaren, насколько я понял, доступ к портам там организован в C++ в виде указателей на объекты.
Например, имя GPIOA - это указатель на порт A.

Индексы битов пронумерованы в виде макросов

а это обращение к регистру BSRR данного порта
GPIOA->BSRR;

а это установка бита №5 в регистре порта
GPIOA->BSRR = GPIO_PIN_5;

И что мешает сделать своё имя для порта?
auto* MyName = GPIOA;

Или даже для регистра
auto& MyReg = GPIOA->BSRR;

и свой номер для бита
auto MyBit=GPIO_PIN_5;

и затем
MyName->BSRR |= MyBit;
или
MyReg |= MyBit;

-----------
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Ответ очень прост: Быстродействие.
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Функция требует дополнительных операций: пропись аргументов, вызов функции, обработку данных, выполнение требуемой операции
там всё повстраивается, разницы не будет в скорости

Добавлено через 1 минуту
Цитата Сообщение от Mr McLaren Посмотреть сообщение
goto зло
это так и есть.

Но мне не попадалось случаев, когда я мог его применить. Он как бы просто не особо нужен

Добавлено через 4 минуты
Цитата Сообщение от Алексей1153 Посмотреть сообщение
там всё повстраивается
а если нет, то это горячий привет разработчикам компилятора. И тогда придётся мучаться с макросами
0
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83
22.06.2025, 12:32  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
насколько я понял, доступ к портам
Я имел ввиду про чтение темы, не нужно было углубляться в изучение STM32 )))
Я не за этим сюда пришёл. Всё таки STM32 я уверен что знаю намного лучше вас.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
насколько я понял, доступ к портам там организован в C++ в виде указателей на объекты.
Например, имя GPIOA - это указатель на порт A.
Индексы битов пронумерованы в виде макросов
а это обращение к регистру BSRR данного порта
GPIOA->BSRR;
а это установка бита №5 в регистре порта
GPIOA->BSRR = GPIO_PIN_5;
Всё верно, так и есть.
Цитата Сообщение от Алексей1153 Посмотреть сообщение
И что мешает сделать своё имя для порта
не мешает. Всё верно, можно и наделать макросов на имена пинов. И их использовать.
Но нужно привязаться к уже созданным макросам.


Всё что здесь приводили по существу вопроса - я и так уже давно проходил и без проблем могу сделать.

Ещё раз повторяюсь. Суть вопроса - привязаться к уже созданным кодогенератором макросам MyName_Pin и автоматически подтягивать к нему макрос MyName_GPIO_Port (он же GPIOX). Всё. только это меня интересует.
Если это невозможно, то тема просто закрыта.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
22.06.2025, 13:12
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Если это невозможно, то тема просто закрыта.
На уровне кода нет.
Но у вас есть среда разработки + сторонние программы помошники, ещё, раз.
Можете в два клика писать подобную ересь автоматически.
21 век, они макросы мучают. Точнее макросы на макросы на макросы. Вот это я понимаю уровень!
0
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83
22.06.2025, 13:23  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
21 век, они макросы мучают. Точнее макросы на макросы на макросы. Вот это я понимаю уровень!
Ну вот так и устроена библиотека STM32. И бредятина там далеко не ограничивается макрысами. И также скажу - вот это уровень! Но приходится плясать под их дудку. Однако стараюсь танцы сокращать.

Цитата Сообщение от SmallEvil Посмотреть сообщение
На уровне кода нет.
жаль. Пойду напьюсь.

Цитата Сообщение от SmallEvil Посмотреть сообщение
Можете в два клика писать подобную ересь автоматически.
После запоя буду пробовать.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
22.06.2025, 13:32
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Однако стараюсь танцы сокращать.
Вы их только продолжаете.
Я всё понимаю, мк, макс. производительность в приоритете.
Два дятла старычка программиста у них на зарплате для обвязки тех самых мк.
Но это не повод впадать в ересь на ровном месте.
0
Нарушитель
622 / 380 / 67
Регистрация: 09.03.2016
Сообщений: 4,172
22.06.2025, 14:13

Почему мне мядаль не дают. Хочу тоже мядаль...
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,874
22.06.2025, 14:37
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Индексы битов пронумерованы в виде макросов
там все по другому
вся периферия раскидана по карте памяти( и все остальное) память занимает 4 гБ.
и все биты имеют конкретные адреса, а вот потом это завернуто структурами и макросами
вот например RCC
C
1
#define RCC                 ((RCC_TypeDef *)RCC_BASE)
указатель на структуру
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef struct
{
  __IO uint32_t CR;
  __IO uint32_t CFGR;
  __IO uint32_t CIR;
  __IO uint32_t APB2RSTR;
  __IO uint32_t APB1RSTR;
  __IO uint32_t AHBENR;
  __IO uint32_t APB2ENR;
  __IO uint32_t APB1ENR;
  __IO uint32_t BDCR;
  __IO uint32_t CSR;
 
 
} RCC_TypeDef;
соответственно адрес
C
1
2
3
4
5
#define RCC_BASE              (AHBPERIPH_BASE + 0x00001000UL)
...................
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x00020000UL)
..................
#define PERIPH_BASE           0x40000000UL /*!< Peripheral base address in the alias region */
можешь написать так
C
1
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
а можно и так
C
1
pllmull = (&(0x40000000U+0x00020000+0x00001000+0х04))& RCC_CFGR_PLLMULL;
но это глупо
файл карты памяти для ознакомления
Вложения
Тип файла: rar stm32f103xb.rar (57.6 Кб, 2 просмотров)
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
22.06.2025, 14:48
Цитата Сообщение от ValeryS Посмотреть сообщение
файл карты памяти для ознакомления
Это вообще для кого?
Кому тут, в этой ветке, ознакамливаться с "этим" ? =))

Добавлено через 2 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
там все по другому
Это к теме не относится, как там и как по другому.
И так уже всем понятно что тема от извращенца к извращенцам.
0
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83
22.06.2025, 14:51  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
файл карты памяти для ознакомления
+

Ну или другими словами она называется стандартная библиотека периферии CMSIS. Чтобы вместо "магических цифр" как раз и пользоваться данными макросами.
библиотека HAL написана поверх данной библиотеки.

Поэтому в STM32 без макросов априори невозможно.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
22.06.2025, 14:56
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Поэтому в STM32 без макросов априори невозможно.
Никто с этим не спорит.
Но посыл ты не уловил и не желаешь.
Что тебе это не нужно.
Проблема - это то что не решается.
У тебя все решаемо вызовом стандартной функции/макроса.

О чем тут ещё говорить.
А твои хотелки, ну видишь, макросам и разработчикам плевать на твои хотелки.
По вполне понятным причинам.

Добавлено через 1 минуту
Писатели для МК и Эмбедет - это реальные придури.
Но наверное только те кто на форумы ходит.
0
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83
22.06.2025, 21:19  [ТС]
Ну кстати, ребята!
Мне в голову пришло такое решение.

Макросы, созданные кубом.
C++
1
2
#define LED1_Pin GPIO_PIN_3
#define LED1_GPIO_Port GPIOA
Создаём дополнительный макрос вручную
C++
1
#define LED1_Pin_GPIO_Port  LED1_GPIO_Port
Ну и подгоняем макросы управления пинами:
C++
1
2
#define SET_PIN(Name_Pin)   Name_Pin##_GPIO_Port->BSRR = (uint32_t) Name_Pin    // Установка единицы на заданном пине
#define RESET_PIN(Name_Pin) Name_Pin##_GPIO_Port->BRR = (uint32_t) Name_Pin     // Установка нуля (сброс) на заданном пине
Ну или так (ещё красивее):
C++
1
2
#define SET_1_PIN(Name_Pin) Name_Pin##_GPIO_Port->BSRR = (uint32_t) Name_Pin    // Установка единицы на заданном пине
#define RESET_PIN(Name_Pin) Name_Pin##_GPIO_Port->BRR = (uint32_t) Name_Pin     // Установка нуля (сброс) на заданном пине
И вуаля, получаем то что я в итоге хотел:
C++
1
2
SET_1_PIN (LED1_Pin);
RESET_PIN (LED1_Pin);
Просто, красиво, понятно.
Что после "демакросизации" выражения принимают чистые значения:
C++
1
2
((GPIO_TypeDef *)((0x40000000UL + 0x00010000UL) + 0x00000800UL))->BSRR = (uint32_t) ((uint16_t)0x0008);
((GPIO_TypeDef *)((0x40000000UL + 0x00010000UL) + 0x00000800UL))->BRR = (uint32_t) ((uint16_t)0x0008);
И это работает. Компилятор без проблем переваривает.
Минусом такого способа является то, что на каждый пин нужно ещё дополнительно вручную наплодить по 1 макросу.
Но зато в аргументе присутствует макрос созданный кодогенератором. Это даёт возможность отследить использование в коде данного пина. т. е. контроль вернулся.

Многие конечно щас закидают меня камнями. Но я уже припас здоровенный щит чтобы укрываться
А с другой стороны. Ну а как ещё то!!!??? Я и просил привести пример без создания лишних макросов.

И да, кстати. Знал бы что в итоге обсуждение выльется непосредственно про STM, то и создал бы тему именно там.
Если модераторы перенесут эту тему туда, я буду только за!
Пойду учить ребят из STM как правльно писать библиотеки
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.06.2025, 21:19

Разбить СString на токены
Здравствуйте! Не могу разбить СString строку на токены. СString id1; char *token; char *str;...

Ошибка: непредвиденный токен
Всем доброго времени суток. Что такое творится в коде? Вроде бы все правильно, но среда зачем-то...

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

Алфавитно-частотный словарь на основе односвязного списка с применением токенов
Здравствуйте, дорогие форумчане! Возникла задача создать алфавитно-частотный словарь на основе...

Как редактировать токены функции strtok?
Всем доброго времени суток! Есть задание, надо в символьной строке найти слова парной длины,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
[golang] Конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов.
alhaos 10.06.2026
Задача Реализовать конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов. Сигнатура func Fetch(urls string, maxConcurrent int) Result Пример urls :=. . .
[golang] Состояние гонки (race condition)
alhaos 10.06.2026
Состояние гонки (race condition) Состояние гонки (Race Condition) — это ошибка, возникающая при одновременном доступе нескольких горутин к одним и тем же данным без должной синхронизации. При этом. . .
Взрослые отношения, и почему они не получаются
kumehtar 09.06.2026
Когда в детстве ребёнок не получает от родителей чего-то важного, он лишается не просто приятных переживаний, а основы для формирования определённых внутренних качеств и навыков. Если ребёнок не. . .
[golang] Worker Pool
alhaos 09.06.2026
Worker Pool Worker Pool — паттерн конкурентной обработки задач в Go. Суть: фиксированное количество горутин-воркеров читают задачи из общего канала и пишут результаты в общий канал результатов. . . .
[golang] Pipeline
alhaos 08.06.2026
Pipeline Pipeline — паттерн конкурентной обработки данных в Go. Суть: данные проходят через цепочку независимых стадий, каждая из которых работает в своей горутине и общается с соседями через. . .
Свет внутри себя
kumehtar 07.06.2026
Пусть это будет здесь lIs4oanZS9Y
Программа для com-порта
Uhbif79 05.06.2026
Всем привет, давно хотел изучить Qt, начинал, бросал, потом снова начинал. И сейчас вот смог написать свою первую программу. До этого имел опыт программирования микроконтроллеров, писал прошивки на. . .
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru