Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/58: Рейтинг темы: голосов - 58, средняя оценка - 4.81
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30

"Циклы" на препроцессоре

13.06.2013, 16:53. Показов 11768. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хотелось данную информацию включить в блог, но пока не понимаю, как это аккуратно сделать. А потому просто тему помещу на форум, а в блоге воткну ссылку

Недавно услышал от студентов, что на препроцессоре можно писать циклы. Понимание того, как работает препроцессор, говорит мне о том, что через препроцессор циклы создавать невозможно. Но на всякий случай полез искать в гугл. Оказалось, что речь идёт о boost'овом разделе boost/preprocessor/iteration. Наподобие этого: http://www.boost.org/doc/libs/... erate.html

В реальности никаких циклов на препроцессоре не строится. У boost'а в этом месте очень глубокие и разветвлённые кишки, но я продемонстрирую на коротком примере общий принцип построения этого раздела boost'а. После чего станет понятно, что в реальности никаких циклов нет, а то, что есть, имеет весьма жёсткие ограничения

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/* Заголовочный файл myboost_iterate.h, иммитирующий boost'овый цикл */
 
#if 0 >= MYBOOST_LOOP_MIN && 0 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(0)
#endif
 
#if 1 >= MYBOOST_LOOP_MIN && 1 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(1)
#endif
 
#if 2 >= MYBOOST_LOOP_MIN && 2 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(2)
#endif
 
#if 3 >= MYBOOST_LOOP_MIN && 3 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(3)
#endif
 
#if 4 >= MYBOOST_LOOP_MIN && 4 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(4)
#endif
 
#if 5 >= MYBOOST_LOOP_MIN && 5 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(5)
#endif
 
#if 6 >= MYBOOST_LOOP_MIN && 6 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(6)
#endif
 
#if 7 >= MYBOOST_LOOP_MIN && 7 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(7)
#endif
 
#if 8 >= MYBOOST_LOOP_MIN && 8 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(8)
#endif
 
#if 9 >= MYBOOST_LOOP_MIN && 19<= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(9)
#endif
 
#if 10 >= MYBOOST_LOOP_MIN && 10 <= MYBOOST_LOOP_MAX
MYBOOST_LOOP_BODY(10)
#endif
Теперь в данном коде мы как будто бы имеем цикл от 4 до 8

C
1
2
3
4
5
#define MYBOOST_LOOP_MIN 4
#define MYBOOST_LOOP_MAX 8
#define MYBOOST_LOOP_BODY(n) \
  int a##n = n;
#include "myboost_iterate.h"
после препроцессора получим на выходе (пустые строки я выкинул, чтобы глаза не резало):

C
1
2
3
4
5
int a4 = 4;
int a5 = 5;
int a6 = 6;
int a7 = 7;
int a8 = 8;
В своём примере я ограничился допустимыми значениями "цикловой переменной" от 0 до 10. В той версии boost'а, в которой я ковырялся, этот диапазон был от 0 до 256. Т.е. имело место быть 257-кратное повторение похожих фрагментов, что и создаёт иллюзию циклов
9
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.06.2013, 16:53
Ответы с готовыми решениями:

Сравнение в препроцессоре
нужна условная компиляция корректна ли такая конструкция (утрирую) #define A 10 #define B 10 #if A==B .............. #endif ...

Размещение функции в препроцессоре
У меня такой вопрос возник можно ли в препроцессор запихнуть какую либо функцию, допустим функцию создания и заполнения массива...

@media в препроцессоре Sass
Непонятно, как записать корректно запрос в Sass (не в Scss): @media screen and (min-width: 320px) and (max-width: 580px) Тяжело...

13
 Аватар для dr.curse
404 / 360 / 36
Регистрация: 11.10.2010
Сообщений: 1,907
13.06.2013, 16:59
Evg, интересно а где вообще могут такие "циклы" пригодится?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.06.2013, 17:01  [ТС]
Временами бывает, что исходник содержит текст, который было бы удобнее сгенерировать, т.к. текст однообразный и похожий. Типа тех переменных с именами a4 - a8, которые в примере
1
13.06.2013, 20:07

Не по теме:

Я как-то пытался "всеми правдами и не правдами" реализовать цикл на препроцессоре, и где-то на форуме эта тема уже вскольз затрагивалась. Идея реализовать сие чудо радилась после ознакомления с nasm'ом, где очень мощный препроцессор.

Цитата Сообщение от aram_gyumri Посмотреть сообщение
интересно а где вообще могут такие "циклы" пригодится?
Пример, вот этот код (nasm)
Assembler
1
2
3
4
5
%assign i 1
%rep 10
print i ; допустим print некий макрос
%assign i i+1
%endrep
после препроцессора развернется в
Assembler
1
2
3
4
5
6
7
8
9
10
print 1
print 2
print 3
print 4
print 5
print 6
print 7
print 8
print 9
print 10
C++
1
2
3
4
5
#define MYBOOST_LOOP_MIN 4
#define MYBOOST_LOOP_MAX 8
#define MYBOOST_LOOP_BODY(n) \
  int a##n = n;
#include "myboost_iterate.h"
вот нечто похожее я и делал (т.е. через инклюды), но на верхний код из первого поста (где много строк) уже ума не хватило. Точнее просто не думал о том, чтобы писать так много строк, при этом количество "итераций" все равно будет ограничено.

0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
13.06.2013, 23:17
Цитата Сообщение от Evg Посмотреть сообщение
Недавно услышал от студентов, что на препроцессоре можно писать циклы.
Можно имелось ввиду метапрограммирование?
Вроде как определение цикла довольно гибкое, и не отрицает кодогенерации.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
14.06.2013, 11:17  [ТС]
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Можно имелось ввиду метапрограммирование?
Вроде как определение цикла довольно гибкое, и не отрицает кодогенерации.
Имелось в виду, что препроцессор можно запрограммировать на то, чтобы он генерировал текст в цикле
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
17.06.2013, 13:42
Все равно что отдать обезьяний труд умной обезьяне. Это очень здорово, что есть такая возможность эмуляции циклов в препроцессоре. Но не лучше ли, если требуется написать
Цитата Сообщение от Evg Посмотреть сообщение
текст однообразный и похожий
то еще немного подумать и написать его в виде какой-нибудь функции? Или можно тогда поглядеть маленький худенький пример с не только созданием и еще и обращением к этим переменным?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
17.06.2013, 14:54  [ТС]
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Или можно тогда поглядеть маленький худенький пример с не только созданием и еще и обращением к этим переменным?
Циклы включили в поставку boost'а. Я практически не программирую на Си++, а потому затрудняюсь тебе привести пример. Если ты на самом деле хочешь его увидеть, то, пройдя по ссылке из первого поста, выудив имя препроцессорного макроса и вбив его в гугл, скорее всего найдёшь в том числе и живые примеры. Сильно подозреваю, что все они вертятся вокруг шаблонов или специализаций шаблонов. В исходниках на Си я подобного ни разу не встречал

Если ты что-то не понимаешь, то это вовсе не означает, что кругом одни идиоты

Добавлено через 3 минуты
Почему именно вокруг шаблонов? Подозреваю, что это в довесок к:
https://www.cyberforum.ru/cpp-... 19864.html
https://www.cyberforum.ru/cpp-... 23714.html
1
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
17.06.2013, 15:20
Интересный пример с хабра: Возможности оптимизации в языках C и C++
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
18.06.2013, 13:10  [ТС]
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Интересный пример с хабра: Возможности оптимизации в языках C и C++
Пример сам по себе очень полезен. Правда автор немного перемудрил и текст получился сложным для начинающих. И на фоне сложности всего текста очень сложно углядеть важную мысль - весь этот геморрой с шаблонами затеивается исключительно ради того, чтобы в коде, полученном после инстанциации шаблонов, было как можно больше сравнений с константами и, соответственно, у компилятора появляется больше возможностей для оптимизаций

К сожалению, конкретно данный пример плохо демонстрирует необходимость создания препроцессорных циклов. А начинающим всегда важно понимать, ради чего затеивается геморрой
0
Заблокирован
19.06.2013, 10:24
только один раз мне пригодились подобные пляски с препроцессором. МБ кому-нибудь будет интересно, я тогда нашел статью на опеннет: http://www.opennet.ru/docs/RUS/cpp/cpp-5.html
там есть раздел про рекурсивные макросы, в тот момент очень хотелось чтобы оно заработало, но:
Стандарт ANSI C не рассатривает рекурсивный вызов макроса как вызов. Он поступает на вывод препроцессора без изменений.
В тот раз все решилось перепилом проекта до того состояния, чтобы вот этого не было:
Цитата Сообщение от Evg Посмотреть сообщение
Временами бывает, что исходник содержит текст, который было бы удобнее сгенерировать, т.к. текст однообразный и похожий
Ну т.е. я знаю что так бывает, но я думаю это не хорошо, с программой что-то не то.

Поддерживать это безобразие неудобно (даже если макрос хороший и отлаживать его уже ненадо), я думаю вы согласитесь.
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
19.06.2013, 11:53  [ТС]
Среди реального использования вспомнился такой случай. Деталей не помню, описываю примерно суть. Программировался эмулятор процессора. Речь шла о системном регистре. В 64-битном регистре кодировались 16 групп по 4 бита. Все группы были симметричны. Между битами было какое-то хитрое соответствие, что аппаратный сигнал взводит бит "A" только в том случае, если взведён бит "B" и погашен бит "C".

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
union Reg_t
{
  uint64_t whole_reg;
  struct
  {
    unisgned a0:1;
    unisgned b0:1;
    unisgned c0:1;
    unisgned d0:1;
 
    unisgned a1:1;
    unisgned b1:1;
    unisgned c1:1;
    unisgned d1:1;
 
    ...
 
    unisgned a15:1;
    unisgned b15:1;
    unisgned c15:1;
    unisgned d15:1;
 
  } fields;
};
 
...
 
Reg_t reg;
unsigned signal;
 
switch (signal)
{
  case 0:
    if (reg.fields.b0 && !reg.fields.c0)
      reg.fields.a0 = 1;
    break;
 
  case 1:
    if (reg.fields.b1 && !reg.fields.c1)
      reg.fields.a1 = 1;
    break;
 
  ...
 
  case 15:
    if (reg.fields.b15 && !reg.fields.c15)
      reg.fields.a15 = 1;
    break;
}
 
...
Здесь именно тот случай, когда вместо массива из 16 элементов, образ регистра желательно держать в структуре с 16-кратным повторением имён полей, потому что это наиболее точно соответствует устройству реального железа, которое эмулируется
2
200 / 87 / 9
Регистрация: 15.11.2010
Сообщений: 472
15.08.2017, 03:14
Evg, спасибо за интересный пример с препроцессором. Суть его ясна. А можно узнать, для какой процессорной архитектуры ты или твоя группа писала эмулятор (я имею в виду пост #12)?
0
15.08.2017, 07:38

Не по теме:

mik-a-el, что-то пошло не так...

Кликните здесь для просмотра всего текста

1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.08.2017, 07:38
Помогаю со студенческими работами здесь

JMetter - вызов функции в препроцессоре
Здравствуйте, написана пользовательская функция для JMetter, реализующая некоторую логику. Необходимо вызывать эту функцию перед отпарвкой...

Циклы с условием, циклы с переменной, вложенные циклы
С условием 1. Ввести натуральное число N и вычислить сумму всех чисел фибоначчи меньших N. Предусмотреть защиту от ввода...

Задача для школы: Научиться использовать циклы с предусловием while и циклы с постусловием do / while
Научиться использовать циклы с предусловием while и циклы с постусловием do / while языка C # для решения задач. Исследовать работу таких...

Циклы. Напечатать числа в виде таблицы, используя только циклы
Напечатать числа в виде таблицы, используя только циклы (массивы и строки не применять): 1 2 2 ...

Циклы. Напечатать числа в виде таблицы, используя только циклы
4. Напечатать числа в виде таблицы, используя только циклы (массивы и строки не применять): 1 2 2 ...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru