简体   繁体   中英

How should I pass a struct in a function?

I am confused because I haven't written C in a while. In C++, we would pass them as references, in order not to copy the whole struct. Does this apply to C too? 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. You might declare the formals to be const pointers to a const structure (this could help the optimizing compiler to generate more efficient code). 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 ).

However, some particular ABIs and calling conventions may mandate particular processing for some few particular structures. 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. 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.

BTW, what really matters on current desktop and laptop processors is the CPU cache . Keeping frequently used data inside L1 or L2 cache will increase performance. 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). 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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