Возвращать указатель на определенное значение в макросе? - PullRequest
0 голосов
/ 08 июня 2010

Можно ли написать макрос, который имеет тип и значение в качестве входных параметров (MACRO(type,value)), и возвращает действительный указатель на местоположение, в котором хранится отправленный value.

Этот макрос должен работать подобно следующей функции, но более общим образом:

int *val_to_ptr(int val){
    int *r = NULL;
    r = nm_malloc(sizeof(*r));
    *r = val;
    return r;
}

Где nm_malloc() - это отказоустойчивый malloc. Использование макроса должно быть совместимо с этим:

printf("%d",*MACRO(int,5));

Можно ли этого достичь?

Ответы [ 4 ]

4 голосов
/ 08 июня 2010

Если вы используете gcc, вы можете использовать операторные выражения :

#define MACRO(type,value) ({ type* t = nm_malloc(sizeof(*t)); *t = (value); t; })
3 голосов
/ 08 июня 2010

Возможно (не проверено):

#define ALLOC_AND_INIT(T, val) *(T*)malloc(sizeof(T))=(val)

Использование

printf("%d\n", ALLOC_AND_INIT(int, 5));  // memory leak :)
2 голосов
/ 08 июня 2010

Вот реализация, которая смоделирована на шаблонах c ++

#define DEFINE_TEMPLATE(type) \
type * val_to_ptr_##type(type val){\
    type * ptr = NULL;\
    ptr = nm_malloc(sizeof(*ptr));\
    *ptr = val;\
    return ptr;\
}

#define USE_TEMPLATE(type,val)\
val_to_ptr_##type(val)

DEFINE_TEMPLATE(int);
int main(){
    printf("%d",*USE_TEMPLATE(int,5));
    return 0;
}

Вы должны были бы явно определить, для каких типов вы его используете, и должны были бы ввести такие вещи, как unsigned int или double complex, иначе вставка токена не будет работать.

Альтернативно используйте

USE_TEMPLATE(type) val_to_ptr_##type

и звоните

USE_TEMPLATE(int)(5);

Не нужно беспокоиться об оценке аргумента

1 голос
/ 08 июня 2010

Любое из решений, использующих malloc(), приведет к утечке памяти в приведенном вами примере. Однако это простое решение, использующее составные литералы C99, не:

#define MACRO(type, val) (&(type){val})
...