在 C 中,结构体可以按值传递/返回,也可以按引用(通过指针)传递/返回。
普遍的共识似乎是前者可以应用于小型结构,在大多数情况下不会受到惩罚。看在任何情况下,直接返回结构是一种好的做法吗? https://stackoverflow.com/a/7550578 and 在 C 中按值传递结构而不是传递指针有什么缺点吗? https://stackoverflow.com/a/161845/5036089
从速度和清晰度的角度来看,避免取消引用都是有益的。但什么算作small?我想我们都同意这是一个小结构:
struct Point { int x, y; };
我们可以相对不受惩罚地传递值:
struct Point sum(struct Point a, struct Point b) {
return struct Point { .x = a.x + b.x, .y = a.y + b.y };
}
还有 Linux 的task_struct
是一个大结构体:
https://github.com/torvalds/linux/blob/b953c0d234bc72e8489d3bf51a276c5c4ec85345/include/linux/sched.h#L1292-1727 https://github.com/torvalds/linux/blob/b953c0d234bc72e8489d3bf51a276c5c4ec85345/include/linux/sched.h#L1292-1727
我们希望不惜一切代价避免放入堆栈(尤其是那些 8K 内核模式堆栈!)。但中等的又如何呢?我认为小于寄存器的结构就可以了。但这些呢?
typedef struct _mx_node_t mx_node_t;
typedef struct _mx_edge_t mx_edge_t;
struct _mx_edge_t {
char symbol;
size_t next;
};
struct _mx_node_t {
size_t id;
mx_edge_t edge[2];
int action;
};
哪个最好经验法则用于确定结构体是否足够小,可以安全地按值传递它(除非出现某些深度递归等情有可原的情况)?
最后请不要告诉我我需要分析。当我太懒/不值得进一步调查时,我要求使用启发式方法。
编辑:根据迄今为止的答案,我有两个后续问题:
如果该结构实际上是怎么办smaller而不是指向它的指针?
如果浅复制是所需的行为(被调用的函数无论如何都会执行浅复制)怎么办?
编辑:不知道为什么这被标记为可能的重复,因为我实际上链接了我的问题中的其他问题。我要求澄清什么是smallstruct 并且我很清楚大多数时候结构应该通过引用传递。