I wrote this macro that lets you put the types of the C arguments in the places where you’d put type annotations in a Julia function definition. Initially, I had the return type at the end of the function, as you would have in a Julia declaration, but now I’ve moved them up front, because they are closer to the variable that gets the value that way.
Sure! Although it’s probably best to make a CcallMacro.jl package first (even unregistered) and get it all working to your satisfaction. Building Julia just to test this will get annoying really quickly.
The more I think about it, the less I like it. The way it is now, everything in the generated code is clearly shown in the input code. I don’t like the idea that a macro with the same name as a built-in function would have different behavior. I’ll write another macro that does what you suggest. I’m thinking @safecall, unless someone has a better name. Or maybe @callc? Not as obviously what it’s changing, but it’s shorter and has the benefit of not “lying” by using the name of a built-in but changing the behavior.
Regarding the issue you referenced, it might be interesting to see if there is a way to statically determine if code is being run in a separate thread or task and see if there is a way to alter the semantics of ccall on that basis. If it were possible, @unsafe_ccall would only be semantically different in concurrent code.
Of course, I don’t know anything about the compiler, and I expect statically analysing for concurrency is probably rather tricky (on the other hand, Julia’s current ability to statically analyse code is already bordering on the occult, so what do I know?)
printf and other varargs functions aren’t called the way normal C functions are. IIRC, each compiler is free to implement the varargs calling convention differently, although in practice I think there’s a fairly standard way to do it (I don’t recall what it is, but I think it involves an implicit **void argument terminated by a NULL pointer (kind of the obvious way you’d do it manually). You would need to emulate the C varargs calling convention in order to call printf correctly.
printf and other varargs functions aren’t called the way normal C functions are
That’s not generally true. They aren’t called like a normal ANSI-C function because they’re typically required to be a normal K&R-C function. (But then those are often required to be the same, so you can usually get away with ignoring the difference.) In practice, some APIs that provide a ... varargs function use a void** implementation underneath (and expose that to users too) because the vararg itself can actually be fairly difficult to work with in the general case since it has a opaque representation.
I’ve successfully used printf with ccall before, just not with argument expansion on the Julia side. The message makes it look like ccall is already doing something macro-y (i.e. it seems not to expand arg…)