什么时候应该通过或返回值一个结构? [英] When should I pass or return a struct by value?

查看:100
本文介绍了什么时候应该通过或返回值一个结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个结构既可以传递/按值返回或通过/由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:


  1. 如果这个结构实际上是的的不是一个指针呢?

如果浅表副本是所期望的行为(被调用的函数将执行浅拷贝呢)?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆