我正在尝试使用宏在C中编写一些可重用的通用类型安全代码,类似于klib的工作方式:
#define Fifo_define(TYPE) \
\
typedef struct { \
TYPE *head; \
TYPE *tail; \
size_t capacity; \
} Fifo_##TYPE, *pFifo_##TYPE; \
\
inline Fifo_##TYPE * Fifo_##TYPE##_init(size_t capacity) { \
Fifo_##TYPE * fifo = calloc(1, sizeof(Fifo_##TYPE)); \
TYPE * data = calloc(capacity, sizeof(TYPE)); \
fifo->head = data; \
fifo->tail = data; \
fifo->capacity = capacity; \
}
// define macros
#define Fifo(TYPE) Fifo_##TYPE
#define Fifo_init(TYPE, capacity) Fifo_##TYPE_init(capacity)
然后,我将其与任何类型参数一起使用:
Fifo_define(int32_t);
...
Fifo(int32_t) *myFifo = Fifo_init(int32_t, 100);
但是,编写此文件非常费事且容易出错,没有IDE编辑器支持(IntelliSense),因此我想知道是否有任何技巧可以使我(也许)添加一些定义,然后包括文件,而不必结束每行与
\
?就像是:
// no idea how to do this, just checking if similar concept is possible
#define FIFO_TYPE int
#define FIFO_NAME Fifo_int
#include <generic-fifo.h>
#undef FIFO_NAME
#undef FIFO_TYPE
我会以某种方式获得所有正确的
struct
和功能。问题是这些宏中有很多参数串联,因此我不确定是否可以用比第一个片段更简单的方式来完成? 最佳答案
在这种情况下,不建议这样做,但是您可以执行类似X-macros的操作:
#define SUPPORTED_TYPES \
X(int) \
X(double) \
X(char)
#define X(TYPE) \
typedef struct { \
TYPE *head; \
TYPE *tail; \
size_t capacity; \
} Fifo_##TYPE, *pFifo_##TYPE;
SUPPORTED_TYPES
#undef X
#define X(TYPE) \
inline Fifo_##TYPE * Fifo_##TYPE##_init(size_t capacity) \
{ \
Fifo_##TYPE * fifo = calloc(1, sizeof(Fifo_##TYPE)); \
TYPE * data = calloc(capacity, sizeof(TYPE)); \
fifo->head = data; \
fifo->tail = data; \
fifo->capacity = capacity; \
}
SUPPORTED_TYPES
#undef X
但这并不能真正改善情况。它摆脱了单个丑陋的
Fifo_define
宏的需要,因此您可以将代码分成几个部分。但是宏观混乱仍然存在。我会建议一些完全不同的方法。两个建议:
在运行时以经典的C方式处理类型通用的东西。使用回调。如有需要,请使用枚举跟踪使用的类型。
C11
_Generic
允许使用各种类型的安全技巧,并可用于逐步淘汰此类混乱的宏。 Example that implements "functors"。宏本身保持最小,并键入了各种类型的不同实现。 (通常,当您进行类型通用编程时,通常这就是您要做的。)