Swift imports fixed-size C array as tuple limit size to 4096 ?

This c struct with fixed array size of 8096 imported ok using Swift with Xcode 10:


typedef struct

{

uint8_t data[8192];

}

TEST_FIXED_ARRAY;

The same code failed to import using Swift with Xcode 11.2

Changing to data[4096]; is working ok however.

This break a lot of my C libraries that implement C fixed-array larger than 4096 elements 😟

Replies

What is the error you get ?


You have probably already read this ; otherwise, may it help ?

h ttps://oleb.net/blog/2017/12/swift-imports-fixed-size-c-arrays-as-tuples/


Here they show that in XCode 6, t-uple limit was 1948 (so it must have grown in later version)

https://stackoverflow.com/questions/24432646/what-is-the-limit-if-any-to-the-tuple-cardinality-in-swift

They mention compilation error 254.


What is surprising is that a size of 8192 worked in XCode 10, no more in XCode 11.

The limit may not only come from Swift itself, but from the t-uple generator that converts array to t-uple ?


I posted a question on Swift.org to get more insight.


EDITED

Got interesting information https://forums.swift.org/t/t-uple-max-size/30635/2


The Swift limit of t-uple size is 2**20. which is way larger than 4096 (2**12)

So the limit you get is not due to this, but more likely to the conversion code from C array to Swift t-uple.

Did you file a bug report for the change between XCode 10 and XCode 11 ?


A bug report was filed (not by me) to Swift.org

https://bugs.swift.org/browse/SR-11747

Its very easy to reproduce.

A simple Swift console project with a C header file containing


// file testc.h

#include <stdio.h>

typedef struct

{

uint8_t data[4097];

}

TEST_FIXED_ARRAY;


In Build Setting specify as Objective-C Bridging Header


And test using the followng Swift code in main.swift


// file main.swift

import Foundation


print("Hello, World!")


let cStruct = TEST_FIXED_ARRAY()

let data = cStruct.data

print(data)


This work without problem using Xcode 10 with size > 4096

But with Xcode 11.2 the following error:


Value of type 'TEST_FIXED_ARRAY' has no member 'data'


So the compiler simply don't see the 'data' member.

Changing the size to 4096 and its fine.


Changing the type to uint16_t and same result, So not related to the member type but the array size.


There is a many article related to Swift interop with C and fixed-array. C fixed are imported as Swift tuple. This is not the problem, I can process the tuple in Swift to get the data bytes. The problem is related to the C array size when imported with Xcode 11.

I understood your point and trust you on the 4096 limit.

My point was just trying to clarify if that came from some Swift limit in t-uple arity. Clearly not.


Did you file a bug report against compiler with this use case ?

Thanks Claude31, your right its not clear to me too if related to a tuple size limit in Xcode 11 / Swift 5 or if the bridging header engine now have a limit on array size when importing C fixed array. I will file a radar on this. Thanks again for sharing.

That will be great to report when you get the answer.


I'm guessing it is linked to the bridging header engine.

I discovered this mechanism to convert to t-uple for fixed size arrays. But also read that it is extremely resource hungry and that another way is to use unsafePointers. But that would probably cause too many changes in your libraries.


Good luck.

Sure, I will report.


Just to clarify, once I got the tuple in Swift I can iterate the tuple to read the data bytes using withUnsafeBytes, no problem here.

However with C array > 4096 the compiler error code say it simply can't access the data element:


"Value of type 'TEST_FIXED_ARRAY' has no member 'data'"


Simply comment the data line in the struct:


//uint8_t data[4097];


And you will see the same error. Of course because now effetively there is no longer a data member.

Uncomment, change the size to 4096 and voilà, the data member is well accessed and printed.

I will file a radar on this.

Thanks! Please post your bug number, just for the record.

Oh, also, as the importer is part of the Swift open source project, you can file a Swift bug about it. That’ll give you greater visibility into its state.

Share and Enjoy

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

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

Bug filed on Apple Feedback # FB7438876

Swift SR-11763

C array larger than 4096 failed to import in Swift with Xcode 11.2

For those reading along at home, there’s a detailed explanation of what’s going on here in SR-11763.

Share and Enjoy

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

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