Thomas R
Thomas R

Reputation: 41

Compiler error on nil using vDSP_normalizeD in an SPM project

How to a pass a nil pointer to a C API in Swift?

More specifically, I'm trying the following:

import Accelerate

let v = [1.0, 2.0]
var m = 0.0
var sd = 0.0
// 3rd arg is of type: UnsafeMutablePointer<Double>?
vDSP_normalizeD(v, 1, nil, 0, &m, &sd, vDSP_Length(v.count))

Documentation for vDSP_normalizeD is found here.

This method of passing nil seems valid for earlier versions of Swift as in this answer. However using Xcode v10.1 / Swift v4.2.1 it gives the following error message:

Nil is not compatible with expected argument type 'UnsafeMutablePointer'

The following solution does not work either:

let p: UnsafeMutablePointer<Double>? = nil
vDSP_normalizeD(v, 1, p, 0, &m, &sd, vDSP_Length(v.count))

giving the following error message:

Value of optional type 'UnsafeMutablePointer?' must be unwrapped to a value of type 'UnsafeMutablePointer'

In earlier versions of Swift the following was possible:

let p = UnsafeMutablePointer<Double>(nil)

but it now generates the following error:

Ambiguous use of 'init'

So, my question is - how do I pass a nil pointer to a C API using a modern version of Swift?

Upvotes: 2

Views: 143

Answers (2)

Thomas R
Thomas R

Reputation: 41

Problem solved!

Thanks OOPer for verifying that it does in fact compile and asking: Are you doing something special to your project?.

I'm maintaining my project through Swift Package Manager and apparently, when generating the Xcode project, it defaults to MACOSX_DEPLOYMENT_TARGET 10.10. However, creating a new project directly via Xcode v10.1 the default is MACOSX_DEPLOYMENT_TARGET 10.12.

The above code requires 10.11 and I did not understand that SPM didn't use a later deployment target. This is all solved now by using a Package.xcconfig file with the variable: MACOSX_DEPLOYMENT_TARGET=10.11.

The documentation didn't help from start either. The help for vDSP_normalizeD doesn't mention anything about target requirements, instead that information is found in the documentation for its float cousin vDSP_normalize.

Btw, this might be obvious for some, but it took me some hours to figure it out. Thanks again OOPer for pointing me somewhat in the right direction.

Upvotes: 2

Camilo Lopez
Camilo Lopez

Reputation: 166

it's hard because I could not test it, but I think is because the initializer:

try this:

let p: UnsafeMutablePointer<Double>? = UnsafeMutablePointer<Double>.init(mutating: nil)

And let me know if it works for you

Upvotes: 0

Related Questions