Wrote a macro to make ccall look a little more like Julia. Need an opinion on the return type placement

Ah, that works for me on Windows. So ccall supports varargs reliably these days as long as you use ... in the argument list?

What if they’re not all Cdoubles?

It has always been supported and this is the syntax. It doesn’t support mixing types though (llvm obviously support that just fine but we just don’t have a syntax for it…) I believe this is documented last time I check…

Note that on x86 (64bit only iirc) vararg floating point is one of the few cases this is needed. The calling convention requires the number of fp vararg to be passed in rax so without the ... the result may be wrong.

We don’t have syntax for that now…

Just cast them all to void* first. har har.

mostly joking.

edit: how’s that now? Ptr{Nothing}(pointer(myobject)). Charming!

One benefit of having a macro is that we could have such a syntax: one option would be to wrap all the varargs in a tuple and call ..., e.g.

@ccall printf(fmt::Cstring, (x::Cdouble, y::Cint)...)::Cint
2 Likes

No that’s not the right calling convention. Whether you cast it first is also a completely orthogonal issue…

1 Like

Not to this question:

I don’t know if it works, but my idea use Ptr{Cvoid}… as your type in the case of printf because it’s going to recast all the arguments anyway based on what’s in the format string.

Or so I am lead to believe…

No. printf looks for certain arguments based on the format string, but ccall still needs to pass them as the correct types.

Well it does something based on the string for sure but that by no mean spare you from following the calling convention. The caller and callee always has to agree on that.

Of course you can make the calling convention passing everything by pointer for vararg, it’s not done for the same reason it’s not for normal argument: there are more efficient way to pass them.

Yes that seems like the best syntax option I’ve seen for this.

Could this be done from within Julia, or would it require C-level changes?

There’s no C-level handling for this either. If you look at Meta.@lower, you’ll see that ccall is actually implemented as a macro. But the lowered form (foreigncall) also doesn’t define support for varargs of different types.

1 Like

I thought so. If you try to use args... in the arguments section, they don’t get expanded, and you get a sort of unexpected error message.