C++ Interoperability in Swift 5.9

Hello, Swift community.

The Swift project has been working on interoperability with C++ for a few years now through the C++ Interoperability Workgroup. We have a pair of vision documents laying out designs for how C++ can be used from Swift and vice-versa, and the implementation of those ideas is ready to be used more widely by Swift programmers as individual proposals evolve. Because language interoperation has a much larger surface area than any individual language feature in either language, the Language Steering Group believes that it's crucial for C++ interoperability to be adopted in real-world projects in order to get broader experience with the feature and shape its design going forward. I'm pleased to announce that Swift 5.9 will include support for C++ interoperability to help facilitate the language evolution feedback cycle, with a new versioning scheme that enables source-stable adoption as the feature changes in response to feedback.

This is the first language interoperability feature that will be going fully through the Swift evolution process. The Language Steering Group believes that a slower process that gives the community an opportunity to gain extensive experience with the feature before reviews begin is critical for the success of this kind of feature. To make two languages work well together requires a deep and careful understanding, not just of how the features of each language will be exposed to each other, but of how they will interact after translation. This is combinatoric complexity, and while we can do our best to design good rules ahead of time, it is inevitable that problems will arise in active use that weren't anticipated or didn't seem so important during design. This is particularly true when the languages don't align perfectly in their features and idioms, or when the languages are still evolving. For example, as we improve Swift's support for non-copyable types, we will gain new and better ways to translate certain kinds of C++ APIs; we would not want C++ interoperability to be locked into a design that didn't consider them.

We went through all of this with Swift’s support for interoperability with Objective-C. Swift 1.0 translated Objective-C APIs very differently from Swift today. We initially had translation rules that we felt were good, straightforward rules, but as we gained experience with both Swift and its interoperation with Objective-C, we realized that they were sometimes causing problems and leading to a programming experience that wasn’t as good as we wanted. We also added some features to Swift, such as error handling, that made it possible to provide much better translations for some pervasive patterns in Objective-C APIs (and demanded we do so). As a result, the translation rules evolved over several releases until we were much more satisfied with the basic results.

At the same time, it is important that Swift not undermine its source-compatibility goals. There may be major changes in the C++ interoperability rules over the next few years as we refine the design and bring it through evolution review, and those changes may require source changes in projects adopting the feature. Programmers should not be forced to make these changes just to adopt new versions of the Swift tools. To make that possible, Swift releases going forward will support multiple compatibility versions of C++ interoperability, just like they support multiple compatibility versions of the base Swift language. A project using the 5.9 compatibility version of C++ interoperability will be insulated from any changes made in 5.10, and it can move to newer compatibility versions at its own pace. To encourage gradual convergence on the newest interoperability rules across the ecosystem, new language compatibility versions (such as the upcoming Swift 6) will also set a minimum compatibility version for C++ interoperability.

The most important reason we are taking these steps is to enable broad community adoption of C++ interoperability, both because we think it will be useful to Swift programmers and because we think that adoption is necessary in order to get to a good design. Community feedback is always important to achieving the best design for a feature. For many features, that feedback can be rooted in experience with similar features in other languages, or it can come from brief experiments with the feature in a toy project. Those are both much less likely to be helpful with language interoperation. Programmers will need real, lived experience with this specific design in order to understand what it does well and what it does poorly.

The Language Steering Group is very excited about the progress with this feature, and we're looking forward to bringing it fully into the language. Please feel free to ask any questions you might have about this process in this thread. Technical questions about how C++ interoperability itself will work, independent of the compatibility story, may be more appropriate in other threads, such as the acceptance thread for the vision for Using C++ from Swift.

John McCall
Language Steering Group Chair


Are there any plans to add some debugging and visibility features for the Interop? I've had issues with the C++ Interop for my Android port and it is not easy to figure out what's going wrong. For example, I'd like to know what C/C++ symbols are exported by each of the pcm module files that Swift imports, and the best I could find is a flag that dumps info about the module and what headers it imports, not a list of symbols.

This would be very useful for the long-standing C interop too, I suggest that it be prioritized.


A post was merged into an existing topic: [Accepted] A vision for using C++ from Swift