UnsafePointer init Xcode 10.2beta

Hi,
We have noticed that the `struct UnsafePointer<Pointee>` init methods are not exposed any more (i.e. public init(_ other: UnsafeMutablePointer<Pointee>)) in Xcode 10.2beta while they are in Xcode10.1. In the documentation and the API changes pages (see https://developer.apple.com/documentation/swift/unsafepointer ) they do not exist at all. Is this an intentional change in Xcode 10.2beta?
Thanks

Replies

I’m not sure I understand the problem here. The following code compiles for me on Xcode 10.2b2:

let ump: UnsafeMutablePointer<Int> = … some value …
let up = UnsafePointer(ump)

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi eskimo,
Thanks for your reply. Let me provide some more information about our problem. In our project we are using an open source framework (Swifter: https://github.com/httpswift/swifter) and the following line of code does not compile on Xcode 10.2beta2 while it compiles in 10.1

return String(cString: UnsafePointer(strerror(errno)))

This is the link to the source file. The error we see on Xcode 10.2 is Ambiguous use of 'init(_:)'

While looking into this we found the following difference in the defintion of UnsafePointer which is not highlightened in the documentation. On Xcode 10.1 the definition looks like:

public struct UnsafePointer<Pointee> {

    /// A type that represents the distance between two pointers.
    public typealias Distance = Int

    /// Creates a new typed pointer from the given opaque pointer.
    ///
    /// - Parameter from: The opaque pointer to convert to a typed pointer.
    public init(_ from: OpaquePointer)

    /// Creates a new typed pointer from the given opaque pointer.
    ///
    /// - Parameter from: The opaque pointer to convert to a typed pointer. If
    ///   `from` is `nil`, the result of this initializer is `nil`.
    public init?(_ from: OpaquePointer?)

    /// Creates a new typed pointer from the given address, specified as a bit
    /// pattern.
    ///
    /// The address passed as `bitPattern` must have the correct alignment for
    /// the pointer's `Pointee` type. That is,
    /// `bitPattern % MemoryLayout<Pointee>.alignment` must be `0`.
    ///
    /// - Parameter bitPattern: A bit pattern to use for the address of the new
    ///   pointer. If `bitPattern` is zero, the result is `nil`.
    public init?(bitPattern: Int)

    /// Creates a new typed pointer from the given address, specified as a bit
    /// pattern.
    ///
    /// The address passed as `bitPattern` must have the correct alignment for
    /// the pointer's `Pointee` type. That is,
    /// `bitPattern % MemoryLayout<Pointee>.alignment` must be `0`.
    ///
    /// - Parameter bitPattern: A bit pattern to use for the address of the new
    ///   pointer. If `bitPattern` is zero, the result is `nil`.
    public init?(bitPattern: UInt)

    /// Creates a new pointer from the given typed pointer.
    ///
    /// - Parameter other: The typed pointer to convert.
    public init(_ other: UnsafePointer<Pointee>)

    /// Creates a new pointer from the given typed pointer.
    ///
    /// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
    ///   result is `nil`.
    public init?(_ other: UnsafePointer<Pointee>?)

    /// Creates an immutable typed pointer referencing the same memory as the
    /// given mutable pointer.
    ///
    /// - Parameter other: The pointer to convert.
    public init(_ other: UnsafeMutablePointer<Pointee>)

    /// Creates an immutable typed pointer referencing the same memory as the
    /// given mutable pointer.
    ///
    /// - Parameter other: The pointer to convert. If `other` is `nil`, the
    ///   result is `nil`.
    public init?(_ other: UnsafeMutablePointer<Pointee>?)

    /// Deallocates the memory block previously allocated at this pointer.
    ///
    /// This pointer must be a pointer to the start of a previously allocated memory 
    /// block. The memory must not be initialized or `Pointee` must be a trivial type.
    public func deallocate()


While in Xcode 10.2beta2 the definition looks like (missing the inits):

public struct UnsafePointer<Pointee> {

    /// A type that represents the distance between two pointers.
    public typealias Distance = Int

    /// Deallocates the memory block previously allocated at this pointer.
    ///
    /// This pointer must be a pointer to the start of a previously allocated memory 
    /// block. The memory must not be initialized or `Pointee` must be a trivial type.
    @inlinable public func deallocate()



Our initial thoughts were that there might have been some changes to the init of the UnsafePointer that led to this compilation error but we might be wrong as well. Any further thought or feedback will be highly appreciated.

FYI, I’m now using Xcode 10.2b3, because I upgraded this morning before opening up DevForums (-:

the following line of code does not compile on Xcode 10.2beta2 while it compiles in 10.1

That code has been incorrect for a while now. I’m not sure when this changed, but we introduced two variants of

String.init(cString:)
, one that takes an
UnsafePointer<CChar>
and another than takes a
UnsafePointer<UInt8>
. This greatly simplifies things, allowing you to deal equally well with C strings that are declared
char *
, like they are by most APIs, and
UInt8 *
, as used, for example, in libxml2.

The upshot of this is there’s no need to explicitly construct an

UnsafePointer
here, you can just pass through the result of
strerror
.
return String(cString: strerror(errno))

It’s a little weird that it now gives you an error. It’s perfectly fine for you to file a source compatibility bug about that, but to my mind it’d be better to just fix your code.

While looking into this we found the following difference in the defintion of

UnsafePointer
which is not highlightened in the documentation.

Yeah, that is weird. When I command-option click

UnsafePointer
in Xcode 10.3b3 I see similar things, that is, an interface that’s missing a bunch of stuff, including the initialisers. Curiously, they’re all there for
UnsafeMutablePointer
. Also, the initialisers are their at compile time, so this issue seems to be limited to the rendering of the generated interface.

I definitely consider that to be bugworthy. It’s hard to say whether it’s a Swift bug or an Xcode bug, but I suspect a Swift bug and so I recommend that you file it here. But if you’re more comfortable with Apple Bug Reporter, that’d work too.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"