C unsigned int[] imported as tuple?


(Thierry Passeron) #1

Hi everyone,

I’m working on a project where I deal with mach here and there, and strangely enough this C struct (from mach/processor_info.h)...

struct processor_cpu_load_info { /* number of ticks while running... */
        unsigned int cpu_ticks[CPU_STATE_MAX]; /* ... in the given mode */
};

is imported in Swift 3 (at least in Xcode8.1 beta) as…

public struct processor_cpu_load_info {

    public var cpu_ticks: (UInt32, UInt32, UInt32, UInt32) /* number of ticks while running... */ /* ... in the given mode */
    ...
}

I find it strange because the index of each UInt32 value depends on machine.h define(d) indexes for CPU_STATE_USER, CPU_STATE_SYSTEM etc…

So the only way to access them in the tuple « format » is to hard code cpu_ticks.0 or cpu_ticks.1 etc… and thus we loose the defined named indexes from machine.h

Am I missing something? What do you guys think of this matter?

For me this tuple should have been at least imported with named fields or even better as [UInt32] array...

Best regards,
Thierry


(Quinn “The Eskimo!”) #2

The latter is not possible because Swift does not currently have support for fixed-size arrays. This is a well-known limitation.

To get the former you’d have to either tweak the Mach headers or give the Swift compiler knowledge about Mach. Both are technically possible but I haven’t seen any concrete efforts in that direction.

Note: The situation with Mach APIs on our platforms is rather nuance. They are officially supported but we strongly encourage folks not to use them because they are very tightly bound to the kernel. In your case (getting CPU load information) using Mach is fine, but for most Mach APIs there are better high-level alternatives.

Feel free to file bug reports for where you’d like to see the system improved here.

<https://developer.apple.com/bug-reporting/>

In the meantime, if I were in your shoes I’d write an extension for `processor_cpu_load_info` that adds the accessors I need:

extension processor_cpu_load_info {
    var user: UInt32 {
        get {
            assert(CPU_STATE_USER == 0)
            return self.cpu_ticks.0
        }
        set {
            assert(CPU_STATE_USER == 0)
            self.cpu_ticks.0 = newValue

        }
    }
}

There’s very little risk hard coding the `.0` because:

* the order of these fields can’t change without breaking binary compatibility

* if you port the code to a new platform, you’ll very likely trip the asserts if the fields get re-ordered

Share and Enjoy

···

On 29 Oct 2016, at 11:34, Thierry Passeron via swift-users <swift-users@swift.org> wrote:

For me this tuple should have been at least imported with named fields or even better as [UInt32] array...

--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware