简体   繁体   English

泛型值初始化分配器

[英]Generic value initialized allocator

Messing around with / learning C. I want a one-liner for moving stack values into the heap and this is the best I could come up with.搞乱/学习 C。我想要一个单行程序来将堆栈值移动到堆中,这是我能想到的最好的方法。

#define defheapify(nm, T, sz) \
  T* heapify_##nm (const T x) { \
    T *nx = malloc(sz); \
    nx[0] = x; \
    return nx; \
  }

defheapify(char, char, sizeof(char));
defheapify(uchar, unsigned char, sizeof(unsigned char));
defheapify(short_int, short int, sizeof(short int));
defheapify(ushort_int, unsigned short int, sizeof(unsigned short int));
defheapify(int, int, sizeof(int));
defheapify(uint, unsigned int, sizeof(unsigned int));
defheapify(long_int, long int, sizeof(long int));
defheapify(ulong_int, unsigned long int, sizeof(unsigned long int));
defheapify(long_long_int, long long int, sizeof(long long int));
defheapify(ulong_long_int, unsigned long long int, sizeof(unsigned long long int));
defheapify(float, float, sizeof(float));
defheapify(double, double, sizeof(double));
defheapify(long_double, long double, sizeof(long double));

It seems to work:它似乎有效:

  short int *si = heapify_short_int(20);
  printf("%d\n", ((int*)si)[0]); /* => 20 */

Is there a better way to accomplish this?有没有更好的方法来实现这一点?

Since this is C:因为这是C:

void * heapify (const void *p, size_t sz) {
    void *x = malloc(sz);
    if (x) memcpy(x, p, sz);
    return x;
}

Then, if you insist:那么,如果你坚持:

#define defheapify(nm, T, sz) \
T* heapify_##nm (const T x) { return heapify(&x, sz); }

But, sz is redundant if you have T , so:但是,如果你有Tsz是多余的,所以:

#define defheapify(nm, T) \
T* heapify_##nm (const T x) { return heapify(&x, sizeof(x)); }

However, if you are only ever concerned about the types you listed in your question, you can use a _Generic switch instead and simplify your interface.但是,如果您只关心问题中列出的类型,则可以改用_Generic开关并简化您的界面。 With the code below, you can remove the task of figuring out the type of the variable or constant you are dealing with.使用下面的代码,您可以消除确定您正在处理的变量或常量的类型的任务。 Just always call heapify_any .总是打电话heapify_any

#define heapify_T(T, X) \
(T *)heapify(&(struct{ T x; }){X}.x, sizeof(T))

#define heapify_G(T, X) T:heapify_T(T, X)

#define heapify_any(X) _Generic( \
X, \
heapify_G(_Bool, X), \
heapify_G(char, X), \
heapify_G(signed char, X), \
heapify_G(unsigned char, X), \
heapify_G(short int, X), \
heapify_G(unsigned short int, X), \
heapify_G(int, X), \
heapify_G(unsigned int, X), \
heapify_G(long int, X), \
heapify_G(unsigned long int, X), \
heapify_G(long long int, X), \
heapify_G(unsigned long long int, X), \
heapify_G(float, X), \
heapify_G(double, X), \
heapify_G(long double, X), \
default:(void)0 \
)

There is no such thing as a literal short (or char or _Bool ) value in C, so you would need a variable or a cast to use the heapify_any macro above. C 中没有文字short (或char_Bool )值这样的东西,因此您需要一个变量或heapify_any才能使用上面的heapify_any宏。

short int *si = heapify_any((short)20);
printf("%hd\n", *si);

Try it online! 在线试试吧!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM