Аргумент макроса C 'хранилище'

Дано:

#define f(x, y) (x+y)
#define g(x, y) (x*y)
#define A 1, 2
#define B 2, 3

int main() {
  int a = f(A);
  int b = g(A);
  int c = f(B);
  int d = g(B);
}

что не работает,

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

Есть ли способ сделать это? [Вы можете изменить f & g; вы даже можете изменить A и то, как я называю макросы. Единственные требования: 1) список аргументов может появляться только один раз 2) он не может быть жестко закодирован... чтобы я мог вызывать макросы с разными аргументами

Если ваше решение не совсем работает, но «почти работает» (для вашего определения «почти»), я бы тоже хотел его услышать, возможно, я смогу подделать его, чтобы оно сработало.

Спасибо!

Изменить: f & g должны быть макросами. Они захватывают имена символов и манипулируют ими.


person anon    schedule 20.02.2010    source источник
comment
Если вы меняете требования исходного вопроса, предоставьте подходящий пример, показывающий, чего вы на самом деле хотите.   -  person Greg Hewgill    schedule 21.02.2010


Ответы (4)


РЕДАКТИРОВАТЬ: версия, которая работает с немодифицированными A и B

#define f(x, y) (x+y) 
#define g(x, y) (x*y) 
#define A 1, 2 
#define B 2, 3

#define APPLY2(a, b) a b
#define APPLY(a, b) APPLY2(a, (b))

int main(int argc, char* argv[])
{
    int x= APPLY(f, A);
    int y= APPLY(f, B);
    int z= APPLY(g, A);
    int d= APPLY(g, B);

    return 0;
}
person MSN    schedule 21.02.2010
comment
Это гениально. Любой, кто понимает, поддержит этот ответ. - person anon; 21.02.2010
comment
Зачем дополнительная косвенность? #define APPLY(a, b) a(b) работает так же хорошо. - person Chris Dodd; 21.02.2010
comment
@ Крис, это так не работает. Я забыл точную причину, но MSVC действительно жалуется на это. - person MSN; 21.02.2010

Вы можете сделать это:

static int f(int x, int y) { return (x+y); }
static int g(int x, int y) { return (x*y); }
#define A 1, 2
#define B 2, 3

Если бы вы использовали компилятор C, который поддерживал нестандартную директиву inline, вы могли бы исключить накладные расходы на вызов функции. И если бы вы использовали C++,

template<T> T f(T x, T y) { return (x+y); }
template<T> t g(T x, T y) { return (x*y); }
#define A 1, 2
#define B 2, 3

который будет работать примерно так же, как ваше предполагаемое макрос-решение C.

Если f и g должны быть макросами, препроцессор C не может передать несколько аргументов макросам без фактической запятой, появляющейся в месте вызова. Для этого вам нужно будет добавить уровень препроцессора выше препроцессора C.

person Greg Hewgill    schedule 20.02.2010
comment
Хорошее решение. Кроме того, даже без встроенной директивы, пока вы используете статическую директиву для функций, оптимизирующие компиляторы, вероятно, все равно будут встроены автоматически. - person Tall Jeff; 21.02.2010
comment
нестандартная встроенная директива. Если на то пошло, если бы он поддерживал стандартный, он, вероятно, встроил бы что-то такое простое. Мы знаем, что спрашивающий использует C99, так как его основная функция не имеет оператора return, но, предположительно, предназначена для определенного поведения ;-) - person Steve Jessop; 21.02.2010

Если вы использовали C99, вы можете использовать составной инициализатор синтаксис для этого путем передачи нескольких аргументов в виде одного массива:

#define f(a) (a[0]+a[1])
#define g(a) (a[0]*a[1])
#define A ((int[]) {1, 2})
#define B ((int[]) {2, 3})

GCC поддерживает этот синтаксис составного литерала как в режиме C89, так и в режиме C++.

person Greg Hewgill    schedule 20.02.2010

Возможно, это то, что вы хотите:

#include<iostream>
using namespace std;

#define A 1, 2

template <typename T>
inline T f(T a, T b) { return a + b; }

int main()
{
    cout << f(A) << endl;
    return 0;
}
person Vlad    schedule 20.02.2010
comment
Вопрос о C, не так ли? - person Steve Jessop; 21.02.2010