简体   繁体   English

我应该如何在函数中传递结构?

[英]How should I pass a struct in a function?

I am confused because I haven't written C in a while. 我很困惑,因为我有一段时间没有写过C. In C++, we would pass them as references, in order not to copy the whole struct. 在C ++中,我们将它们作为引用传递,以便不复制整个结构。 Does this apply to C too? 这也适用于C吗? Should we pass them as pointers, even if we don't want to modify them, in order to avoid copying? 我们应该将它们作为指针传递,即使我们不想修改它们,以避免复制?

In other words, for a function that checks if two structs are equal, we better do 换句话说,对于检查两个结构是否相等的函数,我们最好这样做

int equal(MyRecord* a, MyRecord* b);

and decrease a bit the readability (because of pointers) 并减少一点可读性(因为指针)

or 要么

int equal(MyRecord a, MyRecord b);

will have the same performance? 会有相同的表现吗?

Often, passing pointers is faster - and you'll call equal(&r1, &r2) where r1 and r2 are local struct variables. 通常,传递指针更快 - 你将调用equal(&r1, &r2) ,其中r1r2是局部struct变量。 You might declare the formals to be const pointers to a const structure (this could help the optimizing compiler to generate more efficient code). 您可以将形式声明为const结构的const指针(这可以帮助优化编译器生成更高效的代码)。 You might also use the restrict keyword (if you are sure you'll never call your equal with two identical pointers, eg equal(&r1,&r1) , ie without pointer aliasing ). 你也可以使用restrict关键字(如果你确定你永远不会用两个相同的指针调用你的equal ,例如equal(&r1,&r1) ,即没有指针别名 )。

However, some particular ABIs and calling conventions may mandate particular processing for some few particular structures. 但是,某些特定的 ABI调用约定可能要求对某些特定结构进行特殊处理。 For example, the x86-64 ABI for Linux (and Unix SVR4) says that a struct with two pointers or integral values will be returned thru two registers. 例如, X86-64 ABI为Linux(和Unix SVR4)说,一个struct两个指针或积分值将直通两个寄存器被返回。 This is usually faster than modifying a memory zone with its pointer in a register. 这通常比使用寄存器中的指针修改存储区更快。 YMMV. 因人而异。

So to know what is faster, you really should benchmark. 所以要知道什么是更快,你真的应该基准。 However, passing a large-enough struct (eg with at least 4 integral or pointer fields) by value is almost always slower than passing a pointer to it. 但是,按值传递足够大的struct (例如,至少有4个整数或指针字段)几乎总是比将指针传递给它要慢。

BTW, what really matters on current desktop and laptop processors is the CPU cache . 顺便说一下,当前台式机和笔记本电脑处理器真正重要的是CPU缓存 Keeping frequently used data inside L1 or L2 cache will increase performance. 将常用数据保存在L1或L2缓存中将提高性能。 See also this . 另请参见

What is faster massively depends on the size of the struct and it's use inside the called function. 什么是更快的大大取决于结构的大小它在被调用函数内的使用。

If your struct is not larger than a pointer, passing by value is the best choice (less or equal amount of data needs to be copied). 如果您的结构不大于指针,则按值传递是最佳选择(需要复制的数据量较少或相等)。

If your struct is larger than a pointer, it heavily depends on the kind of access taking place inside the called function (and appearantly also on ABI specifics). 如果你的结构大于指针,那么它在很大程度上取决于被调用函数内部的访问类型(并且在ABI细节上也是如此)。 If many random accesses are made to the struct, it may be faster to pass by value, even though it's larger than a pointer, because of the pointer indirection taking place inside the function. 如果对结构进行了许多随机访问,则传递值可能更快,即使它大于指针,因为指针间接发生在函数内部。

All in all, you have to profile to figure out what's faster, if your struct is larger than a pointer. 总而言之,如果结构大于指针,则必须进行分析以找出更快的结果。

Passing pointers is faster, for the reasons you say yourself. 由于你自己说的原因,传递指针更快。

Actually, I find C more readable than C++ in this case: by passing a pointer in the call, you acknowledge that your paramters might get changed by the called function. 实际上,在这种情况下,我发现C比C ++更具可读性:通过在调用中传递指针,您确认您的参数可能会被调用函数更改。 With C++ references, you can't immediately say that by seeing only the call, you also have to check out the called function prototype to see if it uses references. 使用C ++引用时,您不能立即通过仅查看调用来说明,您还必须检查调用的函数原型以查看它是否使用引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM