Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Passing small structs in C

Name: Anonymous 2013-07-28 13:51

Hi prog. Got a C89 problem.

I want to pass small (less than 64B) structs throught functions that I can't inline because they are used several times elsewhere and are quite big. But it still need it to be very fast.

Should I pass the structs directly (thus copying them) or use a pointer (and getting a dereference penalty) ?

Name: Anonymous 2013-07-28 13:54

both

Name: Anonymous 2013-07-28 14:15

This is a good question.

My gut tells me to copy them, but you could always do a benchmark.

Name: Anonymous 2013-07-28 18:15

Depends on the calling convention. If it fits in a machine word, pass by value, the compiler will optimize it as if you passed in a integer variable. Some calling conventions use between 3-4 CPU registers to pass values to functions. In that case, the struct can be up to 3-4 machine words in size, and the compiler will pack it into the registers for you.

So on 64-bit machines, anything larger than 32 bytes should always be passed by references.

Name: Anonymous 2013-07-28 18:59

>>4
In no calling convention I have ever heard of will arguments be "packed" in registers. It's always one register per argument, and some CPUs have really weird additional contraints regarding sizes and alignment. Unless the struct is 4 members or less, use a pointer, unless you know exactly how your target platform works.

Name: Anonymous 2013-07-28 19:04

>>5
You don't know shit then. MSVC, GCC, and Clang will pack structs into registers on unexported/hidden functions for x64 and other platforms like ARM/ARM64.

Name: Anonymous 2013-07-28 19:11

>>6
There's no need to be mean. But if they are hidden functions they don't need to adhere to a calling convention, so >>6 doesn't contradict >>5.

Name: Anonymous 2013-07-28 19:15

>>4,5

Just tried it out, even in 32-bit 86, Clang will break a struct up and pass it in registers if the function isn't public. You can view the source and assembly output here:

http://gcc.godbolt.org/#{%22version%22%3A3%2C%22filterAsm%22%3A{%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue}%2C%22compilers%22%3A[{%22source%22%3A%22%23include%20%3Cstdio.h%3E\n\nstruct%20suss_t\n{\n%20%20%20%20char*%20text%3B\n%20%20%20%20int%20number%3B\n}%3B\n\nvoid%20xarnicate%28suss_t%20s%29%20{\n%20%20%20%20printf%28\%22String%3A%20%25s%2C%20Number%3A%20%25i\%22%2C%20s.text%2C%20s.number%29%3B\n}%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fclang%2B%2B%22%2C%22options%22%3A%22-O2%20-march%3Dnative%22}]}

Name: Anonymous 2013-07-28 19:18

>>7
Right, but most functions in most programs aren't public. Only when you're building shared libraries or DLLs do they become public, or you've explicitly defined them with a calling convention or as extern "C".

Name: Anonymous 2013-07-28 19:21

>>8
neato

Name: Anonymous 2013-07-28 19:28

>>8
That URL looks all sorts of wrong. You already past the 255 HTTP_GET char limit to make it parsable via old clients and proxies.

Name: Anonymous 2013-07-28 19:34

Unless they're small enough, you still need to dereference to access them.

Thus you should pass only the pieces you need.

Name: Anonymous 2013-07-28 19:35

Fucking feds on your irc channel.

Name: Anonymous 2013-07-28 20:22


Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List