Вы можете использовать memcpy
, чтобы присвоить значение и затем вернуть указатель. Далее используются две разные версии в зависимости от того, является ли ваше начальное значение примитивным типом (целое число, число с плавающей точкой, указатели ...) или оно является struct
. Версия значения использует составной литерал (type){ (value) }
, поэтому он действителен только в C99.
#include <stdlib.h>
#include <string.h>
static inline
void* memcpy_safe(void* target, void const* source, size_t n) {
if (target) memcpy(target, source, n);
return target;
}
#define NM_PTR_RVALUE(type, rvalue) \
((type*)memcpy_safe(malloc(sizeof(type)), &(type){ (rvalue) }, sizeof(type)))
#define NM_PTR_LVALUE(type, lvalue) \
((type*)memcpy_safe(malloc(sizeof(type)), &(lvalue), sizeof(type)))
typedef struct {
int a;
} hoi;
hoi H7 = {.a = 7};
int main() {
int* a = NM_PTR_RVALUE(int, 7);
hoi* b = NM_PTR_LVALUE(hoi, H7);
}
(Добавлена проверка NULL, в которой используется встроенная функция, хотя изначально она не запрашивалась.)
Кстати, в C ++, в отличие от C, оператор присваивания =
возвращает lvalue, поэтому для C ++ вы, вероятно, могли бы играть в игры с этим.