【发布时间】:2015-09-07 22:51:19
【问题描述】:
在 C 中,结构可以通过值传递/返回,也可以通过引用(通过指针)传递/返回。
普遍的共识似乎是,在大多数情况下,前者可以应用于小型结构而不会受到惩罚。见Is there any case for which returning a structure directly is good practice?和Are there any downsides to passing structs by value in C, rather than passing a pointer?
从速度和清晰度的角度来看,避免取消引用可能是有益的。但是什么算小?我想我们都同意这是一个小结构:
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 是一个大结构:
我们希望不惜一切代价避免放入堆栈(尤其是那些 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;
};
确定一个结构是否足够小以安全地按值传递它的最佳经验法则是什么?
最后,请不要告诉我我需要配置文件。当我太懒/不值得进一步调查时,我要求使用启发式方法。
编辑:根据目前的答案,我有两个后续问题:
如果结构实际上比指向它的指针小怎么办?
如果期望的行为是浅拷贝怎么办(被调用的函数无论如何都会执行浅拷贝)?
编辑:不知道为什么这被标记为可能的重复,因为我实际上在我的问题中链接了另一个问题。我要求澄清什么是 small 结构,并且我很清楚大多数时候结构应该通过引用传递。
【问题讨论】:
-
为什么要把整栋房子寄给只需要你地址的人。传递指针总是更可取的。
-
@VinayShukla 传递指针总是至少和传递值一样快。但是如果你做了很多指针解引用,那可能会抵消传递参数的任何微不足道的优势。
-
@Daniel 我同意你的观点,但总是更好地通过指针传递结构而不是通过值传递它。还有许多其他优点,例如按值传递执行浅拷贝,并且修改的值不会被反映。
-
@VinayShukla 为什么这是一个优势?通常,浅拷贝正是需要的行为。
-
这是一个非常好的问题!每个人总是说“小结构也可以”,但没有定义“有多小”。
标签: c shallow-copy