<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="">Yes, the easiest way is to rely on compiler magic for ObjC/C interoperability, but it is also important to know what is really happening.<div class=""><br class=""></div><div class="">My preferred version of the compiler magic is this actually:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> allZerosUUID() -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSUUID</span><span style="font-variant-ligatures: no-common-ligatures" class="">(uuidBytes: [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">UInt8</span><span style="font-variant-ligatures: no-common-ligatures" class="">](repeating: </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span><span style="font-variant-ligatures: no-common-ligatures" class="">, count: </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">32</span><span style="font-variant-ligatures: no-common-ligatures" class="">)).</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">uuidString</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Which is effectively this:</span></div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> allZerosUUID() -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> allZeros = [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">UInt8</span><span style="font-variant-ligatures: no-common-ligatures" class="">](repeating: </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span><span style="font-variant-ligatures: no-common-ligatures" class="">, count: </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">32</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSUUID</span><span style="font-variant-ligatures: no-common-ligatures" class="">(uuidBytes: allZeros).</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">uuidString</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div class="">(Note the use of <span style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px;" class="">let</span> and absence of &).</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 2, 2017, at 1:33 PM, Russell Finn <<a href="mailto:rsfinn@gmail.com" class="">rsfinn@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">I agree that the use of `withUnsafeBufferPointer` to get to the contents of an array makes more sense than `withUnsafePointer`, once you discover the concept of a "buffer pointer" (which a new Swift programmer may not do at first).</div><div class=""><br class=""></div>However, I note that the following code:<div class=""><br class=""></div><div class=""> func allZerosUUID() -> String {</div><div class=""><div class=""> var allZeros = [UInt8](repeating: 0, count: 32)</div><div class=""> return NSUUID(uuidBytes: &allZeros)</div><div class=""> }</div></div><div class=""><br class=""></div><div class="">also compiles without error and returns the intended value. This appears to be supported by the "Constant Pointers" section of the "Interacting with C APIs" chapter of "Using Swift with Cocoa and Objective-C": "When a function is declared as taking an `UnsafePointer<Type>` argument, it can accept ... a `[Type]` value, which is passed as a pointer to the start of the array."</div><div class=""><br class=""></div><div class="">I suspect the availability of `&array` in this context, coupled with an awareness of the existence of `withUnsafePointer(to:)`, is what led my co-worker down the wrong road (and to a puzzling error message); but since we have now discovered two more appropriate ways to write the code in question, perhaps it's not worth worrying about too much.</div><div class=""><br class=""></div><div class="">Thanks to everyone for the discussion.</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Mar 1, 2017 at 7:36 PM, Hooman Mehr <span dir="ltr" class=""><<a href="mailto:hooman@mac.com" target="_blank" class="">hooman@mac.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">Your co-worker needs to get passed the learning curve of these “unsafe” APIs and note that Swift arrays are complex data structures. &allZeros does not give you a pointer to a bunch of zero bytes, but a pointer to a struct that contains the private implementation details of allZeros array. <div class=""><br class=""></div><div class="">Here is the correct way to do it:</div><div class=""><br class=""></div><div class=""><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="">func</span><span style="font-variant-ligatures:no-common-ligatures" class=""> allZerosUUID() -> </span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="">String</span><span style="font-variant-ligatures:no-common-ligatures" class=""> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""><br class=""></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""> </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="">let</span><span style="font-variant-ligatures:no-common-ligatures" class=""> allZeros = [</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="">UInt8</span><span style="font-variant-ligatures:no-common-ligatures" class="">](repeating: </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="">0</span><span style="font-variant-ligatures:no-common-ligatures" class="">, count: </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="">32</span><span style="font-variant-ligatures:no-common-ligatures" class="">)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""><br class=""></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""> </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="">return</span><span style="font-variant-ligatures:no-common-ligatures" class=""> allZeros.</span><span style="font-variant-ligatures:no-common-ligatures;color:#3e1e81" class="">withUnsafeBufferPoint<wbr class="">er</span><span style="font-variant-ligatures:no-common-ligatures" class=""> { </span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="">NSUUID</span><span style="font-variant-ligatures:no-common-ligatures" class="">(uuidBytes: $0.</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="">baseAddress</span><span style="font-variant-ligatures:no-common-ligatures" class="">).</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="">uuidString</span><span style="font-variant-ligatures:no-common-ligatures" class=""> }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">}</span></div></div><div class=""><span style="font-variant-ligatures:no-common-ligatures" class=""><br class=""></span></div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="h5"><div class="">On Mar 1, 2017, at 2:35 PM, Russell Finn via swift-users <<a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a>> wrote:</div><br class="m_-8311670139065548302Apple-interchange-newline"></div></div><div class=""><div class=""><div class="h5"><div dir="ltr" class="">Thanks to Joe and Quinn for their answers. I have a related followup — a co-worker learning Swift wrote the following function:<br class=""><div class=""><br class=""> func allZerosUUID() -> String {<br class=""> var allZeros = [UInt8](repeating: 0, count: 32)<br class=""> return withUnsafePointer(to: &allZeros) { zerosPtr in<br class=""> return NSUUID(uuidBytes: zerosPtr).uuidString<br class=""> }<br class=""> }<br class=""><br class="">but was puzzled that Xcode 8.2.1 gave an error "Cannot convert value of type 'UnsafePointer<_>' to expected argument type 'UnsafePointer<UInt8>!'" on the line with the NSUUID initializer. Their expectation was that `zerosPtr` would be of type `UnsafePointer<UInt8>` because `allZeros` is of type `[UInt8]`. </div><div class=""><br class=""></div><div class="">They discovered that they could work around this by adding a call to `withMemoryRebound`:<br class=""><br class=""> func allZerosUUID() -> String {<br class=""> var allZeros = [UInt8](repeating: 0, count: 32)<br class=""> return withUnsafePointer(to: &allZeros) { zerosPtr in<br class=""> zerosPtr.withMemoryRebound(to: UInt8.self, capacity: allZeros.count) { zerosPtr in<br class=""> return NSUUID(uuidBytes: zerosPtr).uuidString<br class=""> }<br class=""> }<br class=""> }<br class=""><br class="">but felt that this should be unnecessary. Perhaps I'm missing something simple, but I was unable to explain this compiler behavior; can anyone on the list do so?</div><div class=""><br class=""></div><div class="">(Yes, I did point out that they could pass `&allZeros` directly to `NSUUID(uuidBytes:)`.)<br class=""></div><div class="gmail_extra"><div class="gmail_quote"><br class=""></div><div class="gmail_quote">Thanks — Russell</div><div class="gmail_quote"><br class=""></div></div></div></div></div><span class="">
______________________________<wbr class="">_________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-users</a><br class=""></span></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></div></body></html>