我正在为一个在内部使用类似 Lisp 的数据结构(即 cons 单元)的东西编写代码。因此,将 cons 结构体的两个字段成员称为
x->car
和 x->cdr
是有意义的。
正如您可能期望的那样,我分配给这些字段。有时它是链接的,如
x->cdr->cdr->car
所示(是的,在执行此操作之前我会检查以确保中间值有效)。
因为它是 Lisp,但是我希望能够为它们使用 Lisp 名称,例如
x->caddr
,但这显然行不通,因为它是链式指针,而不是单个指针。
目前我正在使用一堆预处理器宏,如下所示:
#define car(x) ((x)->car)
#define cdr(x) ((x)->cdr)
#define caar(x) car(car(x))
#define cadr(x) car(cdr(x))
#define cdar(x) cdr(car(x))
#define cddr(x) cdr(cdr(x))
#define caaar(x) car(caar(x))
// and so on all the way up to caaaaaar / cddddddr
这允许我编写像
caddr(x) = y
这样的东西并让它工作,因为宏扩展为可以分配给的有效左值。
但是,宏不会进行类型检查。如果我不小心传入了一个没有
car
和 cdr
指针的值,则错误消息很难准确地找出问题所在。
它也感觉像是一个拼凑,就像大多数“预处理器黑客”一样。
我正在寻找某种方式来表达这一点:
有什么指点吗?
(没有双关语)
@273K评论回复
inline object*& car(object* x) { return x->car; }
inline object*& cdr(object* x) { return x->cdr; }
inline object*& caar(object* x) { return car(car(x)); }
inline object*& cadr(object* x) { return car(cdr(x)); }
inline object*& cdar(object* x) { return cdr(car(x)); }
inline object*& cddr(object* x) { return cdr(cdr(x)); }
inline object*& caaar(object* x) { return car(caar(x)); }
// and so on