Yes. For example consider this function to add two 2D points, which accepts and returns all variables entirely in xmm registers: https://gcc.godbolt.org/z/hPGKrh6W4 (surprisingly, gcc generates some fairly odd assembly code here)
This idea about communicating size/alignment is actually something we're doing on the port of RediSearch to Rust [0]. We have an "opaque sized type" which is declared on the Rust-side, and has its size & alignment communicated to the C-side via cbindgen. The C-side has no visibility into the fields, but it can still allocate it on the stack.
It's a bit ugly due to cbindgen not supporting const-generic expressions and macro-expansion being nightly-only. It seems like this will be a generally useful mechanism to be able to use values which are not traditionally FFI-safe across FFI boundaries.
> When you want to embed a type, you need its definition, but you don’t actually need the full definition. You just need the size/alignment.
Aren't there ABI cases where e.g.
would be passed in e.g. fp registers whereas would not?Yes. For example consider this function to add two 2D points, which accepts and returns all variables entirely in xmm registers: https://gcc.godbolt.org/z/hPGKrh6W4 (surprisingly, gcc generates some fairly odd assembly code here)
This idea about communicating size/alignment is actually something we're doing on the port of RediSearch to Rust [0]. We have an "opaque sized type" which is declared on the Rust-side, and has its size & alignment communicated to the C-side via cbindgen. The C-side has no visibility into the fields, but it can still allocate it on the stack.
It's a bit ugly due to cbindgen not supporting const-generic expressions and macro-expansion being nightly-only. It seems like this will be a generally useful mechanism to be able to use values which are not traditionally FFI-safe across FFI boundaries.
[0]: https://github.com/RediSearch/RediSearch/blob/cfd364fa2a47eb...
This has reawakened the nightmares about Objective-C++