Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-11763] C array larger than 4096 failed to import in Swift with Xcode 11.2 #54170

Closed
swift-ci opened this issue Nov 11, 2019 · 6 comments
Closed
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-11763
Radar rdar://problem/57056345
Original Reporter Datagram (JIRA User)
Type Bug
Status Resolved
Resolution Won't Do
Environment

macOS 10.15.1

Xcode 11.2

Also filed on Apple Feedback #

FB7438876

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 07ffc60aaca6251835926f69d4e71aa3

relates to:

  • SR-14061 Slowdown until eventual abort trap 6 + segfault when compiling with headers containing C structs with large arrays

Issue Description:

This c struct with fixed array size of 8192 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

Error message say: Value of type 'TEST_FIXED_ARRAY' has no member 'data'

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


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.

Also filed on Apple Feedback #

FB7438876

@beccadax
Copy link
Contributor

I actually screened your radar this morning. I guess you'll just get the reply a little sooner!


Thanks for reporting this issue. This behavior change was intentional—we found that extremely large tuples like this one were causing compiler performance problems and were too clumsy to use in practice anyway.

Although the data field is no longer visible from Swift, the compiler still knows it’s there. You should find that it’s still allocating space for it:

print(MemoryLayout<TEST_FIXED_ARRAY>.size)    // => 4097

And it will also copy the contents as necessary—they just aren’t directly exposed to Swift.

As a workaround, I’d recommend writing a C function along the lines of void withUnsafeMutablePointerToFixedArray(TEST_FIXED_ARRAY *array, void (^body)(char *ptr)) and using that to access the array. If you want to get fancy, you could even use NS_SWIFT_NAME("TEST_FIXED_ARRAY.withUnsafeMutablePointer(self:_:)") to make Swift import it as a method on TEST_FIXED_ARRAY. This will not only work in current Swift compilers, but probably be easier to manipulate than a giant tuple.

@swift-ci
Copy link
Collaborator Author

Comment by Rejean Lamy (JIRA)

Thanks Brent for the explanation.

I hope Swift will soon support fixed array natively so we can import such large C array directly.

@swift-ci
Copy link
Collaborator Author

Comment by Rejean Lamy (JIRA)

Brent,

I suggest lifting this limit.

  • This limit of 4096 is arbitrary.

  • We can create a tuple with a lot more than 4096 elements directly in a Swift code but the C header importer refuse to do it.

  • This breaks the compatibility with Swift code created previously with Xcode 10 / Swift 4.2 in the case of importing C headers.

My point is not whether it makes sense for a Swift programmer to work with a large tuple and where to put a limit, but the fact that the absence of other mechanisms penalizes the programmer to access C structs array members.

So, I suggest that you lift this limit until you find another acceptable solution.

On several discussion threads I notice requests and proposals to implement of Swift fixed-size array type.

Is fixed-size array support coming soon?

@beccadax
Copy link
Contributor

The 4096 limit was selected because it matches C’s BUFSIZ constant, which is used in structs defined in some C headers.

We’d love to do something about fixed-size arrays, but they would probably require new generics features. Another possibility would be to import these fields as having with*(_:) methods like the one I suggested writing by hand; this would require fewer language changes but wouldn’t be as graceful.

@swift-ci
Copy link
Collaborator Author

Comment by Rejean Lamy (JIRA)

Brent,

A short-term solution based on a new Swift API as withUnsafeMutablePointerToFixedArray ... would be really good.
And a long-term solution based on a new fixed-size array type will be wonderful!
The important thing is we can access these fields directly from Swift.

Thanks for considering.

@swift-ci
Copy link
Collaborator Author

Comment by Jeff Verkoeyen (JIRA)

I believe I'm encountering this issue again in https://bugs.swift.org/browse/SR-14061.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

2 participants