我正在实现一个不需要内存分配的堆栈,只要它嵌入一个特殊的结构就可以采用任何结构。类似于GNU 的 List实现。
任何结构必须嵌入才能在堆栈中工作的结构是:
struct stack_elem {
struct stack_elem *next;
};
我想与堆栈一起使用的结构是:
struct node {
double number;
char character;
int isNumber;
struct stack_elem elem;
};
所以堆栈看起来像这样:
node: node:
+---------+ +---------+
|number | |number |
+---------+ +---------+
|character| |character|
+---------+ +---------+
|isNumber | |isNumber |
+---------+ +---------+
|elem | |elem |
| *next |----->| *next |
+---------+ +---------+ etc....
我正在编写一个宏stack_entry
,用于将嵌入式elem
结构转换为其容器node
结构。这是我到目前为止所尝试的。stack_entry
将按如下方式使用:
struct stack_elem *top = peek(&stack);
struct node *converted_node = stack_entry(top, struct node, elem);
stack_entry
将采用指向 的指针,stack_elem
要转换为的节点的类型以及该节点中元素的成员字段的名称。我尝试了几种方法来做到这一点,但都没有奏效。我意识到这STACK_ELEM
指向该next
项目,因此我尝试仅减去elem
from的偏移量struct node
,但这不起作用。以下是我尝试过的一些也不起作用的事情:
#define stack_entry(STACK_ELEM, STRUCT, MEMBER) \
((STRUCT *) &(STACK_ELEM) - offsetof (STRUCT, MEMBER))
#define stack_entry(STACK_ELEM, STRUCT, MEMBER) \
((STRUCT *) ((uint8_t *) &(STACK_ELEM)->next \
- offsetof (STRUCT, MEMBER)))
什么是正确的算术?如果它是结构中的最后一个元素,为什么不减去 的偏移量,从而产生节点next
的偏移量?elem
GNU Listlist_entry
宏定义为:
#define list_entry(LIST_ELEM, STRUCT, MEMBER) \
((STRUCT *) ((uint8_t *) &(LIST_ELEM)->next \
- offsetof (STRUCT, MEMBER.next)))
这是如何运作的?next
当它应该在同一个节点而不是那个节点中获取容器结构时,为什么会涉及到这里next
?