<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=""><span style="font-family: LucidaGrande;" class="">The &amp; operator isn't exactly an address-of operator. Does &amp;arr[0] even return a pointer to the inner buffer? When you use &amp; with properties (and possibly with subscripts as well), Swift may create a local, copy the property value to it, pass a pointer to that local, and copy back the output to the property.</span><div class="" style="font-family: LucidaGrande;"><br class=""></div><div class="" style="font-family: LucidaGrande;">Anyway, you are probably looking for Array.withUnsafe(Mutable?)BufferPointer:</div><div class="" style="font-family: LucidaGrande;"><br class=""></div><div class="" style="font-family: LucidaGrande;">arr.withUnsafeMutableBufferPointer { foo($0, $0.count) }</div><div class="" style="font-family: LucidaGrande;"><br class=""></div><div class="">
<span class="Apple-style-span" style="border-collapse: separate; line-height: normal; border-spacing: 0px;">Félix</span>
</div>

<br class=""><div><blockquote type="cite" class=""><div class="">Le 23 déc. 2015 à 20:35:09, Árpád Goretity via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi everyone,<div class=""><br class=""></div><div class="">I was recently trying to use a C API (LLVM for the record) that required passing an array to a function in the form of a pointer and a size. I couldn't find a straightforward way to pass a null pointer to the function in question conditionally (when the array is empty), since the following – simplified – code doesn't currently typecheck:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; // C function with signature: void foo(T *ptr, unsigned size)</div><div class="">&nbsp; &nbsp; // imported into Swift as: (UnsafeMutablePointer&lt;T&gt;, UInt32) -&gt; ()</div><div class="">&nbsp; &nbsp; var arr: [T] = []</div><div class="">&nbsp; &nbsp; foo(arr.count &gt; 0 ? &amp;arr[0] : nil, UInt32(arr.count))</div><div class=""><br class=""></div><div class="">The error is: result values in '? :' expression have mismatching types 'inout T' and '_'&nbsp;</div>















<div class=""><br class=""></div><div class="">This does not make sense since although `nil` is typeless by itself, its concrete type should still be able to be inferred from the context (just like it is inferred correctly if one writes</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; condition ? 1 as Optional&lt;Int&gt; : nil</div><div class=""><br class=""></div><div class="">which is an analogous scenario.)</div><div class=""><br class=""></div><div class="">Since the inout operator (&amp;) can only be used in function call arguments (so it's not exactly C's address-of), I believe that there's no easy way of elegantly passing a null pointer when the array is empty. (Yes, I could write two almost-identical calls, but meh…) And even if there is one (and I'm just missing it), the fact that the above code does not work seems inconsistent to me.<br clear="all" class=""><div class=""><br class=""></div><div class="">I also realized that this specific issue generalizes to the (in)ability of passing one-past-end pointers – which would be equally valid and even more convenient in the above case, as the callee does not dereference the passed pointer when the count is 0, but in general, it can be applied to functions accepting [begin, end + 1) ranges.</div><div class=""><br class=""></div><div class="">The problem here is that a one-past-end pointer does not reside at a valid index (pretty much by definition), so bounds checking kicks in and kills the program.</div><div class=""><br class=""></div><div class="">My proposed solutions:</div><div class=""><br class=""></div><div class="">&nbsp;– Extend type inference for unsafe pointers and nil, so that when a value is passed by address to a function, it's not only the result of an &amp;-expression that has its type inferred to be (or implicitly converted to) Unsafe[Mutable]Pointer, but if there's a nil somewhere around, such as the one in the example above, it gets promoted to that type too, just like NULL in C or nullptr in C++.</div><div class=""><br class=""></div><div class="">&nbsp;– Stop overloading the inout '&amp;' operator and using it for C-style address-of operations. I could imagine a similar, but distinct operator or even a library function (something along the lines of unsafeAddressOf) that specifically yields the physical address of its operand as an unsafe C pointer, and which is thus first-class in the sense that it may be used anywhere other expressions may be, not just as immediate call arguments.</div><div class=""><br class=""></div><div class="">&nbsp;– Make array bounds checking more lenient when passing pointers to array elements into C functions. Bounds checking should, in these cases, allow indexing the one-past-end element of an array if (and only if) it is the argument of the address-of operator.</div><div class=""><br class=""></div><div class="">Comments and questions are welcome (you might need clarification, as it's 2:35 AM here when I'm writing this…)</div><div class=""><br class=""></div><div class="">Cheers,</div><div class=""><br class=""></div>-- <br class=""><div class="gmail_signature"><div dir="ltr" class=""><font face="monospace" size="3" class="">Author of the Sparkling language</font><div class=""><font face="monospace" size="3" class=""><a href="http://h2co3.org/" target="_blank" class="">http://h2co3.org/</a><br class=""></font></div><div class=""><font face="monospace" size="3" class=""><br class=""></font></div></div></div>
</div></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=iRI3beHTe3UxYAHTlV3lA38zIPfHMhyuRzgTmGKV6k74XsJ-2FcmlQFzq5YyxhID55gn-2BpAkb3KZs69Zlrog-2FUqWRSfDoQ-2BgPmiOeGi5kg8e4Cfj2kV6HGpHxIDq69Gc9U17V3ACOZ-2FC5YtEPQhnDZeEPN4oQt58VNEW5uNGemHahsMkivTcDRUaQHzBuJg6QdiUG38iczYcghDAD8AxB2CQCQZtpvFiMa-2FI4QDQWW-2BSg-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>