什么时候应该通过或返回值一个结构? [英] When should I pass or return a struct by value?
问题描述
一个结构既可以传递/按值返回或通过/由C基准(通过指针)返回。
A struct can be either passed/returned by value or passed/returned by reference (via a pointer) in C.
普遍的共识似乎是,前者可以在大多数情况下适用于小结构不会受到处罚。请参见是否有任何情况下,它返回一个结构直接是好的做法呢?并的是否有任何C缺点传递结构由值,而不是传递指针?
The general consensus seems to be that the former can be applied to small structs without penalty in most cases. See Is there any case for which returning a structure directly is good practice? and Are there any downsides to passing structs by value in C, rather than passing a pointer?
这避免了间接引用可以从两者的速度和清晰度的角度来看是有利的。但作为的小的才算数?我想我们都同意这是一个小的结构:
And that avoiding a dereference can be beneficial from both a speed and clarity perspective. But what counts as small? I think we can all agree that this is a small struct:
struct Point { int x, y; };
这是我们可以相对不受惩罚值传递:
That we can pass by value with relative impunity:
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
是一个大的结构:
And that Linux's task_struct
is a large struct:
<一个href=\"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内核模式堆栈!)。但是,什么是中等左右的?我假设结构不是寄存器较小的罚款。但是关于这些是什么?
That we'd want to avoid putting on the stack at all costs (especially with those 8K kernel mode stacks!). But what's about middling ones? I assume structs smaller than a register are fine. But what about these?
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;
};
什么是最好的拇指的用于确定结构是否足够小,它是安全的,按价值计算为传递(短情有可原的,如一些深层次的递归)规则?
What is the best rule of thumb for determining whether a struct is small enough that it's safe to pass it around by value (short of extenuating circumstances such as some deep recursion)?
最后,请不要告诉我,我需要的资料。我问了一个启发式的,当我懒得用/它不值得进一步调查。
Lastly please don't tell me that I need to profile. I'm asking for a heuristic to use when I'm too lazy/it's not worth it to investigate further.
编辑:我有一个基于答案到现在为止二后续问题:
I have two followup questions based on the answers so far:
-
如果这个结构实际上是的小的不是一个指针呢?
如果浅表副本是所期望的行为(被调用的函数将执行浅拷贝呢)?
What if a shallow copy is the desired behavior (the called function will perform a shallow copy anyway)?
编辑:不知道为什么,这让标记为可能重复的,因为我其实在我的问题联系起来的另一个问题。我要求澄清什么是的小的结构和很清楚,大多数时间结构应该通过引用传递。
Not sure why this got marked as a possible duplicate as I actually link the other question in my question. I'm asking for clarification on what constitutes a small struct and am well aware that most of the time structs should be passed by reference.
推荐答案
在小型嵌入式架构(8/16苦味) - 总是的按指针传递,为不平凡的结构不适合这种微小的寄存器,这些机器一般都注册饥饿为好。
On small embedded architectures (8/16-bitters) -- always pass by pointer, as non-trivial structures don't fit into such tiny registers, and those machines are generally register-starved as well.
在PC类的架构(32位和64位处理器) - 按值传递的结构确定提供了的sizeof(mystruct_t)LT; = 2 * sizeof的(mystruct_t *)
键,功能也不多(通常超过3个机器字的价值的)其他参数。在这种情况下,一个典型的优化编译器将通过/在寄存器中返回的结构或寄存器对。然而,X86-32,这些建议应采取与盐粮沉重,由于非凡的寄存器pressure一个X86-32编译器必须处理 - 传递指针仍可能更快,因为减少了寄存器溢出和灌装。
On PC-like architectures (32 and 64 bit processors) -- passing a structure by value is OK provided sizeof(mystruct_t) <= 2*sizeof(mystruct_t*)
and the function does not have many (usually more than 3 machine words' worth of) other arguments. Under these circumstances, a typical optimizing compiler will pass/return the structure in a register or register pair. However, on x86-32, this advice should be taken with a hefty grain of salt, due to the extraordinary register pressure a x86-32 compiler must deal with -- passing a pointer may still be faster due to reduced register spilling and filling.
通过对PC-喜欢值返回的结构,另一方面,遵循相同的规则,保存的事实是,当结构是由指针返回,该结构要填写应的通过在的指针类型,以及 - 否则,被调用者和调用者都不得不在如何管理该结构中的内存卡一致。
Returning a structure by value on PC-likes, on the other hand, follows the same rule, save for the fact that when a structure is returned by pointer, the structure to be filled out should be passed in by pointer as well -- otherwise, the callee and the caller are stuck having to agree on how to manage the memory for that structure.
这篇关于什么时候应该通过或返回值一个结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!