The & operator isn't exactly an address-of operator. Does &arr[0] even return a
pointer to the inner buffer? When you use & 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.
Anyway, you are probably looking for Array.withUnsafe(Mutable?)BufferPointer:
arr.withUnsafeMutableBufferPointer { foo($0, $0.count) }
Félix
> Le 23 déc. 2015 à 20:35:09, Árpád Goretity via swift-evolution
> <[email protected]> a écrit :
>
> Hi everyone,
>
> 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:
>
> // C function with signature: void foo(T *ptr, unsigned size)
> // imported into Swift as: (UnsafeMutablePointer<T>, UInt32) -> ()
> var arr: [T] = []
> foo(arr.count > 0 ? &arr[0] : nil, UInt32(arr.count))
>
> The error is: result values in '? :' expression have mismatching types 'inout
> T' and '_'
>
> 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
>
> condition ? 1 as Optional<Int> : nil
>
> which is an analogous scenario.)
>
> Since the inout operator (&) 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.
>
> 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.
>
> 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.
>
> My proposed solutions:
>
> – 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 &-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++.
>
> – Stop overloading the inout '&' 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.
>
> – 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.
>
> Comments and questions are welcome (you might need clarification, as it's
> 2:35 AM here when I'm writing this…)
>
> Cheers,
>
> --
> Author of the Sparkling language
> http://h2co3.org/ <http://h2co3.org/>
>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution