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.
Just because no one ever did it and it’s not strictly necessary. ccall probably should have been a macro in the first place but it predates macros in the language.
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.
One question: can’t we, while doing minor developments to stdlib for example, download the latest nightly build and create a sysimg with PackageCompiler?
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?)
There’s precedence. For example, @show vs show. It seems natural (to me) that the macro does approximately the same thing as the function, but with less typing.
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…)