powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Макросы в Lisp стиле, возможно ли это: (+ , (-
25 сообщений из 31, страница 1 из 2
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39283992
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно сабж. Можно ли исполнить макрос такого, вида, чтоб понимал код ниже:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int main(void) {
  printf("v1=%d\n", ADD(1));
  printf("v2=%d\n", ADD(1, 1));
  printf("v3=%d\n", ADD(1, 1, 1));
  printf("v4=%d\n", ADD(1, 1, 1, 1));
  printf("v5=%d\n", ADD(1, 1, 1, 1, 1));
  printf("v6=%d\n", ADD(1, 1, 1, 1, 1, 1));
  printf("v7=%d\n", ADD(1, 1, 1, 1, 1, 1, 1));
  printf("v8=%d\n", ADD(1, 1, 1, 1, 1, 1, 1, 1));
}



C++ ные оверлоды с дефолтами, темплейты и прочую подобную C++ ерунду не предлагать, интересует тру С, который код выше преобразует в код вида

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int main(void) {
  printf("v1=%d\n", (1));
  printf("v2=%d\n", (1 + 1));
  printf("v3=%d\n", (1 + 1 + 1));
  printf("v4=%d\n", (1 + 1 + 1 + 1));
  printf("v5=%d\n", (1 + 1 + 1 + 1 + 1));
  printf("v6=%d\n", (1 + 1 + 1 + 1 + 1 + 1));
  printf("v7=%d\n", (1 + 1 + 1 + 1 + 1 + 1 + 1));
  printf("v8=%d\n", (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1));
}





собственно как аналог лисповских (+ 1 2), (+ 1 2 3 4 5 6) ну и т.д.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284006
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно взять stdarg.h и сделать функцию с переменным числом аргументов которая
просто решит данную задачу.

А если нужен альтернативный макро-процессор то... я не уверен это будет
"честное" С решение.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284011
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonМожно взять stdarg.h и сделать функцию с переменным числом аргументов которая
просто решит данную задачу.

А если нужен альтернативный макро-процессор то... я не уверен это будет
"честное" С решение.

функция не катит, т.к. ее параметры не могут быть вычислены-соптимизированы компилятором заранее.
альтернативный макропроцессор не нужет, в родном достаточно фич.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284022
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
nojavaСобственно сабж. Можно ли исполнить макрос такого, вида, чтоб понимал код ниже:
Все что можно на темплейтах - можно и на макросах, единственное отличие - на макросах сообщения об ошибке компилятора всегда в строке начала определения макроса, т.е. можно такое. Variadic Macros есть.
Так что вперёд и с песней!
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284026
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaC++ ные оверлоды с дефолтами, темплейты и прочую подобную C++ ерунду не предлагать, интересует тру С, который код выше преобразует в код вида
А это уже нам решать, предлагать или нет )))
nojavaфункция не катит, т.к. ее параметры не могут быть вычислены-соптимизированы компилятором заранее.
Катит.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
// реализация
template <typename Arg>
constexpr Arg add(Arg arg)
{
    return arg;
}

template <typename Arg1, typename... Args>
constexpr Arg1 add(Arg1 arg1, Args... args)
{
    return arg1 + add(args...);
}

// использование
template <int n> struct compile_time_only
{
    static const int value = n;
};

int main()
{
    cout << compile_time_only<add(1, 2, 3)>::value << endl;
    return 0;
}
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284039
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинВсе что можно на темплейтах - можно и на макросах, единственное отличие - на макросах сообщения об ошибке компилятора всегда в строке начала определения макроса, т.е. можно такое. Variadic Macros есть
В макросах перегрузки нет. Поэтому рекурсию делают через одно место )))
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284043
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА это уже нам решать, предлагать или нет )))
сказано же - стандартный темплейт головного мозга не нужен.

решение на стековерфлоу уже найдено, была проблема с кроссплатформой, NUMARGS в MSVC не работает как надо.
это поборолось тоже, отдельно

но вы продолжайте, продолжайте постать свои темплейт-функции укатайки, как проявление клоунады вполне себе покатит :)
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284049
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaрешение на стековерфлоу уже найдено,
... но поскольку его код надо полчаса разобрать с поллитрой, то его стыдно опубликовать )))
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284051
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskynojavaC++ ные оверлоды с дефолтами, темплейты и прочую подобную C++ ерунду не предлагать, интересует тру С, который код выше преобразует в код вида
А это уже нам решать, предлагать или нет )))
nojavaфункция не катит, т.к. ее параметры не могут быть вычислены-соптимизированы компилятором заранее.
Катит.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
// реализация
template <typename Arg>
constexpr Arg add(Arg arg)
{
    return arg;
}

template <typename Arg1, typename... Args>
constexpr Arg1 add(Arg1 arg1, Args... args)
{
    return arg1 + add(args...);
}

// использование
template <int n> struct compile_time_only
{
    static const int value = n;
};

int main()
{
    cout << compile_time_only<add(1, 2, 3)>::value << endl;
    return 0;
}



А так не лучше?

http://ideone.com/0e9Mpe
Код: plaintext
1.
2.
template<typename T, typename ...Agrs>
constexpr T add(T val, Agrs ...args) { T res = val; T tmp[] = { res += args ... }; return res; }
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284052
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВася УткинВсе что можно на темплейтах - можно и на макросах, единственное отличие - на макросах сообщения об ошибке компилятора всегда в строке начала определения макроса, т.е. можно такое. Variadic Macros есть
В макросах перегрузки нет. Поэтому рекурсию делают через одно место )))

есть в макросах перегрузка. кури мануал на тему _generic

твоя категоричность продолжает неимоверно радовать.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284054
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskynojavaрешение на стековерфлоу уже найдено,
... но поскольку его код надо полчаса разобрать с поллитрой, то его стыдно опубликовать )))

да пожалуйста.

http://stackoverflow.com/questions/824639/variadic-recursive-preprocessor-macros-is-it-possible
http://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments

если у тебя разбор подобного требует поллитры и полчаса... может стоить прекратить пить?
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284060
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
nojavaAnatoly Moskovskyпропущено...

... но поскольку его код надо полчаса разобрать с поллитрой, то его стыдно опубликовать )))

да пожалуйста.

http://stackoverflow.com/questions/824639/variadic-recursive-preprocessor-macros-is-it-possible
http://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments

если у тебя разбор подобного требует поллитры и полчаса... может стоить прекратить пить?



Вы правы, шаблоны это громоздко и непонятно: http://ideone.com/QPylGU
Код: plaintext
1.
2.
template<typename T, typename ...Agrs>
constexpr T add(T val, Agrs ...args) { T tmp[] = { val += args ... }; return val; }




макросы намного понятней, лаконичней и легче поддаются отладке: http://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments
Код: plaintext
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.
#define PP_NARG(...) \
         PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
         PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
          _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,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
         _61,_62,_63,N,...) N
#define PP_RSEQ_N() \
         63,62,61,60,                   \
         59,58,57,56,55,54,53,52,51,50, \
         49,48,47,46,45,44,43,42,41,40, \
         39,38,37,36,35,34,33,32,31,30, \
         29,28,27,26,25,24,23,22,21,20, \
         19,18,17,16,15,14,13,12,11,10, \
         9,8,7,6,5,4,3,2,1,0

/* Some test cases */


PP_NARG(A) -> 1
PP_NARG(A,B) -> 2
PP_NARG(A,B,C) -> 3
PP_NARG(A,B,C,D) -> 4
PP_NARG(A,B,C,D,E) -> 5
PP_NARG(1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3,4,5,6,7,8,9,0,
         1,2,3) -> 63
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284062
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинВы правы, шаблоны это громоздко и непонятно: http://ideone.com/QPylGU
Код: plaintext
1.
2.
template<typename T, typename ...Agrs>
constexpr T add(T val, Agrs ...args) { T tmp[] = { val += args ... }; return val; }



ты сначала это в MSVC скомпилируй, потом приходи, ага.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284072
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaесть в макросах перегрузка. кури мануал на тему _generic
Даже стесняюсь спросить, но в вопросе есть слово MSVC
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284082
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинА так не лучше?

http://ideone.com/0e9Mpe
Код: plaintext
1.
2.
template<typename T, typename ...Agrs>
constexpr T add(T val, Agrs ...args) { T res = val; T tmp[] = { res += args ... }; return res; }


Ну, оно может короче, но ничем не лучше тех макросов по читаемости, т.к. надо разбираться что там происходит. Например tmp там только для побочных эффектов.
Ну и только свежие компиляторы с С++14 такое проглотят.
А то что я привел - это чистый С++11.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284145
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВася УткинА так не лучше?

http://ideone.com/0e9Mpe
Код: plaintext
1.
2.
template<typename T, typename ...Agrs>
constexpr T add(T val, Agrs ...args) { T res = val; T tmp[] = { res += args ... }; return res; }


Ну, оно может короче, но ничем не лучше тех макросов по читаемости, т.к. надо разбираться что там происходит. Например tmp там только для побочных эффектов.
Ну и только свежие компиляторы с С++14 такое проглотят.
А то что я привел - это чистый С++11.


интереса ради решил покомпилировать ваши закорючки, сравнить дизассемблер.
и? оба ваших чудаковых "решения" в принципе не понимают вызов функции, ибо тупо constexpr

приплыли.

парни, вы серьезно? какой смысл делать variadic param ADD макрос, чтоб он принимал и выдавал только константу?
в задаче compile time only не ставилось.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284177
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskynojavaесть в макросах перегрузка. кури мануал на тему _generic
Даже стесняюсь спросить, но в вопросе есть слово MSVC

я еще могу понять претензию, что требование компиляции под GCC 4.4 (или 2.98), уже неактуальна.

но выбрасывать единственный реально работающий C/C++ компилятор для платформы, которая занимает 90% десктопа и минимум 50% серверов...
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284189
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaпарни, вы серьезно? какой смысл делать variadic param ADD макрос, чтоб он принимал и выдавал только константу?
в задаче compile time only не ставилось.
Затем, что топик стартер в порыве высокомерия не догадался привести реальный юзкейс, и пришлось привести абстрактный пример )))
Уберите constexpr, и будет вам не только константа.

nojavaя еще могу понять претензию, что требование компиляции под GCC 4.4 (или 2.98), уже неактуальна.

но выбрасывать единственный реально работающий C/C++ компилятор для платформы, которая занимает 90% десктопа и минимум 50% серверов...
Так что там, откомпилируется _generic в MSVC? )))
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284224
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaесть в макросах перегрузка. кури мануал на тему _generic

твоя категоричность продолжает неимоверно радовать.
Кстати покурил это ваш мануал.
1) _Generic конечно же никакого отношения к перегрузке в макросах не имеет.
Это конструкция самого языка, а не препроцессора.
Соответственно никакой перегрузки в макросах с его помощью естественно не сделаешь. Но спасибо что указали на мою категоричность )))

2) Отдельно позабавило, как С-шники смело (почти как и вы) рассказывают, чего не умеет С++.
Оказывается в С++ нельзя разные типы возвращать в перегруженных функциях.

Generic selection is similar to overloading in C++ (where one of several functions is chosen at compile time based on the types of the arguments), except that it makes the selection between arbitrary expressions, which, unlike function overloads, may have different return types and even different value categories.

3) Сама эта конструкция _Generic - яркий пример упоротости С-шников.
Вместо того чтобы сделать нормальные перегрузки с одинаковыми именами и разным набором параметров, они добавляют в язык синтаксического монстра.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284225
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предлагаю засунуть в макрос что то типа i++ и угадать что получится.

Можно и функцию с таким же эффектом, если ТС так хочет.

Но что написал Уткин, я вообще не понял.

Я бы написал так
Код: plaintext
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.
#include <stdio.h>
#include <stdarg.h>

inline int add_int(int n, va_list arg)
{
	int x = va_arg(arg, int);
	if (n == 1) return x; 
		else
	return x + add_int(n - 1, arg);
}

inline int add(int n, ...)
{
	va_list arg;
	va_start(arg, n);
	
	return add_int(n, arg);
}

int main() {
	
	int a = 2;
	
	printf("%d\n", add(1, 77));
	printf("%d\n", add(2, 77, 22));
	printf("%d\n", add(3, 5, 7, 13));
	
	return 0;
}


Ассемблер gcc 4.9.2 -O3
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
00401380 <_add>:
  401380:	53                   	push   ebx
  401381:	8b 5c 24 08          	mov    ebx,DWORD PTR [esp+0x8]
  401385:	8b 44 24 0c          	mov    eax,DWORD PTR [esp+0xc]
  401389:	83 fb 01             	cmp    ebx,0x1
  40138c:	74 18                	je     4013a6 <_add+0x26>
  40138e:	83 eb 01             	sub    ebx,0x1
  401391:	31 d2                	xor    edx,edx
  401393:	31 c9                	xor    ecx,ecx
  401395:	83 c2 01             	add    edx,0x1
  401398:	01 c1                	add    ecx,eax
  40139a:	39 da                	cmp    edx,ebx
  40139c:	8b 44 94 0c          	mov    eax,DWORD PTR [esp+edx*4+0xc]
  4013a0:	75 f3                	jne    401395 <_add+0x15>
  4013a2:	01 c8                	add    eax,ecx
  4013a4:	5b                   	pop    ebx
  4013a5:	c3                   	ret    
  4013a6:	31 c9                	xor    ecx,ecx
  4013a8:	eb f8                	jmp    4013a2 <_add+0x22>
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284231
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglНо что написал Уткин, я вообще не понял.
Да, там не сильно очевидно.
Вот это
Код: plaintext
1.
val += args ...


заменяется при инстанцировании на
Код: plaintext
1.
val += arg1, val += arg2, val += arg3,...


Соответственно, как побочный эффект от инициализации массива tmp будет прибавление к val всех остальных аргументов.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284246
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я с начала топика подумал-было что автор хочет средствами макропросессора С
реализовать каррирование ADD.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284256
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaСобственно сабж. Можно ли исполнить макрос такого, вида, чтоб понимал код ниже:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int main(void) {
  printf("v1=%d\n", ADD(1));
  printf("v2=%d\n", ADD(1, 1));
  printf("v3=%d\n", ADD(1, 1, 1));
  printf("v4=%d\n", ADD(1, 1, 1, 1));
  printf("v5=%d\n", ADD(1, 1, 1, 1, 1));
  printf("v6=%d\n", ADD(1, 1, 1, 1, 1, 1));
  printf("v7=%d\n", ADD(1, 1, 1, 1, 1, 1, 1));
  printf("v8=%d\n", ADD(1, 1, 1, 1, 1, 1, 1, 1));
}



C++ ные оверлоды с дефолтами, темплейты и прочую подобную C++ ерунду не предлагать, интересует тру С, который код выше преобразует в код вида

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int main(void) {
  printf("v1=%d\n", (1));
  printf("v2=%d\n", (1 + 1));
  printf("v3=%d\n", (1 + 1 + 1));
  printf("v4=%d\n", (1 + 1 + 1 + 1));
  printf("v5=%d\n", (1 + 1 + 1 + 1 + 1));
  printf("v6=%d\n", (1 + 1 + 1 + 1 + 1 + 1));
  printf("v7=%d\n", (1 + 1 + 1 + 1 + 1 + 1 + 1));
  printf("v8=%d\n", (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1));
}




собственно как аналог лисповских (+ 1 2), (+ 1 2 3 4 5 6) ну и т.д.


А почему тебе именно макрос нужен ?
Чем функция не устраивает ?
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284261
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выше автор писал
в задаче compile time only не ставилось.
значит вызов функции или цепочки функций ему вполне себе подходит.
...
Рейтинг: 0 / 0
Макросы в Lisp стиле, возможно ли это: (+ , (-
    #39284262
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivА почему тебе именно макрос нужен ?
Чем функция не устраивает ?
Не верит в инлайн )))
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Макросы в Lisp стиле, возможно ли это: (+ , (-
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]