1

I'm using swift array as output buffer for a function that takes a pointer and fills it, like this:

var buffer : [Int32] = ...
tehFillFunc(UnsafeMutablePointer<Int32>(buffer))

This works fine, the problem is that compiler is complaining that Variable 'buffer' was never mutated; consider changing to 'let' constant, which I don't want to do as I'm pretty sure it was mutated in my fill function.

So, is there a way to silence it? (I could just do some dummy set, but I'd prefer to do it properly).

Edit: As requested complete example code that shows the problem (c is not even necessary):

class ViewController: UIViewController {

    func fill(sth: UnsafeMutablePointer<Int32>) {
        sth[0] = 7
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        var array = [Int32].init(count: 10, repeatedValue: 0)
        fill(UnsafeMutablePointer<Int32>(array))
        print("\(array)")
    }
}

However, the solution was already posted. In simplest form:

        fill(&array)
5
  • 2
    I do not get any warning with your code ... Commented Jun 14, 2016 at 10:31
  • @MartinR You are right, I wonder how the original C function is declared. Commented Jun 14, 2016 at 10:34
  • 2
    I assumed void tehFillFunc(int *ptr);. Commented Jun 14, 2016 at 10:34
  • 2
    Please update your question with a (small) self-contained example demonstrating the problem. Commented Jun 14, 2016 at 11:12
  • And it seems to be independent on the c/swift as source of the function - just the swift declaration form mattered. Commented Jun 14, 2016 at 11:32

3 Answers 3

2

Usually you need to have specify buffer size. And in this case I prefer following solution:

let bufferSize = 1000
var buffer = [Int32](count: bufferSize, repeatedValue: 0)
tehFillFunc(&buffer)
Sign up to request clarification or add additional context in comments.

1 Comment

Well, this is the closest to what I need. Looks like it was simpler than I thought.
1

There's a method on Array for this purpose:

var buffer : [Int32] = ...

buffer.withUnsafeMutableBufferPointer {
    tehFillFunc($0.baseAddress)
}

I makes sure the array is alive at least until withUnsafeMutableBufferPointer returns. As it takes an inout parameter, buffer has to be a var.

6 Comments

That's what I also thought until some time ago, but as I understand forums.developer.apple.com/thread/47085, using withUnsafeMutableBufferPointer is not necessary for a single function invocation: "Swift guarantees that pointers you generate this way will remain valid for the duration of the function call."
@MartinR The good thing about using it that it correctly behaves in the mutating case. If, for example, there's a didSet observer on buffer it would correctly be called once after withUnsafeMutableBufferPointer returns.
I see, that is a good point. (But I still wonder where the compiler warning should come from, I cannot reproduce it.)
@MartinR I was wondering if the function was actually declared tehFillFunc(const int *ptr);. Another reason could be an outdated Swift version... But I agree, it would be great if the OP would fill in this missing information.
In that case the function could not assign new values to the pointed-to elements.
|
1

How about this one?

let buffer = [Int32](unsafeUninitializedCapacity: bufferSize) { buffer, initializedCount in
    tehFillFunc(buffer.baseAddress)
    initializedCount = bufferSize
}

1 Comment

I don't even work on that project anymore, but this looks much better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.