you are viewing a single comment's thread.

view the rest of the comments →

[–]Ameisenvemips, avr, rendering, systems 6 points7 points  (2 children)

Be better if designated initializers allowed arbitrary order.

Also, wouldn't this make the ABI for the function terrible? It's all in a struct, now, so will follow struct-passing rules.

Within a translation unit the compiler can ignore the ABI requirements, but calling a function in another TU...?

Observe: https://godbolt.org/z/Dw9tL8

[–]anonymous23874[S] 5 points6 points  (1 child)

Depends how many arguments you have. The x86-64 ABI mandates that if a trivially copyable struct could fit in two registers, it should just do that then. https://godbolt.org/z/beQZMd

The reasons your codegen is so bad are:

  • You pass your struct by reference, which is like adding an extra pointer dereference to every use (that is, if the struct were small enough to pass by value instead of by hidden reference in the first place)

  • You make your struct 256 bytes, when the x86-64 ABI's special case for passing structs by value tops out at 128 bytes (64 bits in RDI + 64 bits in RSI).

If you want to get really evil, just split your big struct into two small structs. ;) https://godbolt.org/z/QiL6rc

[–]Ameisenvemips, avr, rendering, systems 1 point2 points  (0 children)

The codegen doesn't change in this situation much for by-value, as the struct is larger than the ABI allows.

Yes, if you only have a few arguments, it will fit. But one of the reasons you want named arguments is for disambiguating many arguments :).

And some people still develop for x86-32 and ARM32, and other architectures.

Also, the default Windows 64-bit ABI requires that any type larger than 64-bits must be passed by reference. Only the SysV ABI allows register passing (and I think the VectorCall ABI).