I think we do want to do this, but it needs a formal proposal and some more implementation work to check that the arguments are actually valid for C. For instance, you wrote this:
// Exposed to C ABI as `void printInfoWithInput(char * input, int count)` @c(printInfoWithInput) func printInfo(from input: String, count: Int) { … }
But there's no way to go from a char *
to a String
without taking the count
into account (unless you want to guarantee that input
is also null-terminated). This also isn't compatible with the behavior of @objc
, which translates String
to NSString *
.
The other big question is whether arbitrary other Objective-C types or types bridgeable to Objective-C are allowed, since they aren't cross-platform.
@cdecl func getOpaqueThing() -> Any
// `id getOpaqueThing(void)`, or an error?
@cdecl func compute(input: Foundation.Data) -> Int
// `intptr_t computeWithInput(NSData *input)`, or an error?
// Also, 'intptr_t' or 'NSInteger'? 'long' unfortunately wouldn't work on Windows.
I imagine different people will have different opinions on this. One way out would be to allow both @objc
and @cdecl
to be present on a function, and for them to enforce different rules. (We'd probably also want to consider allowing @cdecl
on enums in this case too, but then again standard C doesn't have enums with underlying types.)
I do think @c
is a little too short to be a good attribute name, but I guess @cdecl
no longer fits our naming convention.