<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hi, all. I'll try to shed some light on both macros and variadic functions.</div><div class=""><br class=""></div><div class="">Macros are the easy ones. Obviously, a macro like this can't be imported as a function:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">#define UNIQUE_NAME(prefix) prefix##__COUNTER__</div></blockquote><div class=""><br class=""></div><div class="">But here's a trickier one:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">#define NAME(windowStruct) windowStruct.attrs->name</div></blockquote><div class=""><br class=""></div>In this case, there's probably a pair of structs in mind, one with an 'attrs' field, and one with a 'name' field. But the compiler can't know that just from the macro. In fact, the macro may be intended for use over many structs, all with an 'attrs' field (much like C++ templates). Swift can't express this.<div class=""><br class=""></div><div class="">We'd definitely be glad to improve our handling of macros that are unambiguous, but importing <i class="">all</i> macros is not a goal we can ever reach. In most cases, the best workaround is to write a static inline C function that just calls through to the macro.</div><div class=""><br class=""></div><div class="">---</div><div class=""><br class=""></div><div class="">Okay, C variadics. The main problem with C variadics is that they're antithetical to Swift's idea of memory safety. I mean, sure, calling <i class="">any</i> C function means you're stepping outside Swift's safety, but at least the call is well-typed, and if you're trafficking in UnsafePointer, the function says so (and you probably had to make or get one at the call site). With a variadic function, you can pass total garbage and not be aware of it, and the function will just crash.</div><div class=""><br class=""></div><div class="">A <i class="">practical</i> problem with C variadics is that they're at odds with <i class="">Swift's</i> variadics model. Swift variadics, like C# or Java, specify a particular type for <i class="">all</i> of the variadic arguments—they're all Strings, or Ints, or AnyObjects. C variadics, on the other hand, allow a mix of types, and they're all passed differently. Now, we can certainly do this—we do have Clang, after all—but it's Yet Another Difference between Swift and C that people might have to think about. (For variadics with <a href="https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-g_t_0040code_007bsentinel_007d-function-attribute-3219" class="">null sentinels</a>, does the compiler insert the sentinel? Does it check whether one of the values is nil? What if it's <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html#//apple_ref/occ/instm/NSDictionary/initWithObjectsAndKeys:" class="">alternating value-key pairs</a>?)</div><div class=""><br class=""></div><div class="">That's mostly it. They're even less safe than the rest of C, and they make things more complicated in Swift. As of Swift 2.2 we do at least import them as unavailable instead of missing entirely, so you get a reasonable error message (as Ryan noticed). It's a lot easier to do that than to actually implement it, though; we basically fake it with a Swift variadic function that has the same signature.</div><div class=""><br class=""></div><div class="">We <i class="">do</i> import the 'va_list' type, and there's a helper in the standard library, 'withVaList', to safely build a va_list that you can pass to a C function. That's mostly intended for providing a Swift variadic interface that calls through to the underlying implementation. (It's very platform-specific code.) If a function doesn't have a va_list variant, however, Joe's right that the only correct workaround today is, again, a static inline C function. (If you look at the particular pull requests Ryan called out, you'll see they all shim to a C function to do exactly this.)</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I hope this clears up some of the issues in both areas. They're not happy answers, and like everything there's probably room for improvement, but they are areas with enough complexity that we'd need to be careful about changing them.</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On Jan 6, 2016, at 16:28 , Thomas Catterall via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">It seems to me that an interesting tool in the swift toolchain would be one that could generate implementations of methods in circumstances like this, using, for instance, CPP macros as hints for function prototypes. Then again, I might be entirely wrong and I'd be happy to be corrected!</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Tom<br class=""><br class="">Sent from my iPhone</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="">On 5 Jan 2016, at 16:57, Kate Stone <<a href="mailto:katherine_stone@apple.com" class="">katherine_stone@apple.com</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 5, 2016, at 12:32 PM, Ryan Lovelett via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Just to be clear though the intent of my question was not to quibble<br class="">with compiler error messages. My real question is how are we meant to do<br class="">systems programming with Swift on Linux if we cannot call ioctl?<br class=""></div></div></blockquote><br class=""></div><div class="">In the absence of an automatic mechanism for importing the definition of variadic functions you can still define your own prototypes and bind them to the system implementation. For example, this declaration:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">@_silgen_name("ioctl") func ioctl(fildes: CInt, request: UInt64, result: UnsafePointer<Int>) -> Int</span></div><div class=""><br class=""></div></div>… gives you a non-variadic interface to ioctl that you can use for invocations that conform to this specific convention. You can define as many overloads as you wish, and so long as you’re cautious about which one you’re using for a given request you should be able to make progress.<div class=""><br class=""></div><div class="">The same basic strategy can be applied to any variadic functional interfaces. Ideally you’d want to hide this implementation detail behind a more Swift-friendly API where the request type is implied to create a more type-safe interface.<div class=""><br class=""><div class=""><font color="#424242" class="" style="font-family: 'Lucida Grande'; font-size: x-small;">Kate Stone</font><span class="" style="font-family: 'Lucida Grande'; font-size: x-small;"> </span><font color="#009193" class="" style="font-family: 'Lucida Grande'; font-size: x-small;"><a href="mailto:k8stone@apple.com" class="">k8stone@apple.com</a></font></div><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="font-family: LucidaGrande; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="font-family: Times; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><font face="Lucida Grande" size="1" class=""><font color="#009193" class=""></font> Xcode <font color="#424242" class="">Low Level Tools</font></font></div><div class=""><font face="Lucida Grande" size="1" class=""><font color="#424242" class=""><br class=""></font></font></div></div></div></div></div></div></div></div></div></div></div></blockquote><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=ZEz4qHYnXhPr3bBPu-2FxP4tN3HfWKL-2FtJpqkQ0gkOVSBX9V98c-2FvVH4XB1OlZnaQJlCaBXFVx83MLo8EXgqapGMRt5IH6GGpZFp2IXqJvQf92XeT8r1BvWP37uE6gam6-2BpyJg8QbW2EXAZ5IAygQmQN3IK7hn-2Fs7-2FGrD87gpxW95mllOuo0dlBp-2B0XVr5bxnzHjNKUMtJ9uAg-2BTEfOXUYgBCZYH1RJmsRgP0yZMGzXns-3D" alt="" width="1" height="1" border="0" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><span class="Apple-converted-space"> </span></span><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">swift-dev mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:swift-dev@swift.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">swift-dev@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-dev" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-dev</a></div></blockquote></div><br class=""></div></body></html>