Report: Swift and C++ interoperability project progress in the Swift-5.7 time frame

This post presents the progress that the Swift and C++ interoperability workgroup has made during the first eight months of this year by highlighting the major documentation and compiler changes that landed in that time frame. The span of this time frame stretches from the initial workgroup announcement until the middle of September of this year when Swift-5.7 was released. Note that the majority of compiler changes in this post haven’t made it into the Swift-5.7 release, but they will make it into the next planned release of Swift.

:busts_in_silhouette: Workgroup

The Swift and C++ interoperability workgroup now has a page on the Swift website that talks about what the workgroup does and describes how to join it.

:memo: Documentation

:rocket: Using C++ APIs From Swift

  • Designed and implemented a safe model for importing C++ types and their members that prevents accidental misuse of inner pointers and references in Swift. The vision document provides more details about this model.
  • Extended previously prototyped support for bridging C++ types with reference semantics to Swift class types by adding support for bridging custom C++ reference counting operations to Swift.
  • Added a C++ standard library overlay to allow easier conversion between Swift and C++ standard library types.
    • For example, you can now convert a C++ std::string to a Swift String using the String(cxxString:)initializer.
  • Designed and implemented a safe and ergonomic iterator bridging model from C++ to Swift.
    • This allows the use of C++ collection types like std::vector in for-in loops in Swift, and also provides access to Swift’s collection APIs like map and filter for such types.
  • Improved support for bridging C++ operators to Swift.
  • Improved Swift’s compatibility with the Foundation framework in Objective-C++ mode (i.e. when C++ interoperability is enabled).

:boomerang: Using Swift APIs from C++

  • Designed and implemented support for bridging Swift structs, enums, and classes to C++.
  • Added support for bridging functions, methods, properties and initializers to C++.
  • Designed and implemented initial support for bridging generic functions and types to C++.
    • This allows C++ code to call Swift generic APIs that don’t have generic requirements.
  • Added initial support for using Array and Optional Swift standard library types from C++.
  • Added an overlay for the Array type that allows it to be used in C++ ranged-based for loops.
  • Added initial support for bridging functions that throw to C++.

:railway_track: Looking ahead

In the time frame of the next Swift release, the workgroup is going to focus on taking some of the currently prototyped interoperability features through Swift’s evolution process. The workgroup intends to finalize and publish the vision documents and is planning to submit several evolution pitches. The workgroup is going to prioritize bug fixes and stabilization of these compiler features as well. Additionally, the workgroup is planning to work on related ecosystem features like improved debugging and editor tooling support for projects that use interoperability.

I would like to thank the members of the C++ interoperability workgroup and the Swift community for their contributions to this project. The workgroup has made great strides towards the vision of greater bi-directional interoperability between C++ and Swift and we’re excited for what will come next.

51 Likes

Thanks for writing this up and keeping us informed. Much appreciated!

2 Likes

Is there a reason why this is not String(cppString:)? “cpp” is generally understood to refer to C++: it’s the standard file extension for C++ implementation files, and GitHub-Flavored Markdown recognizes it as the language name for C++ when introducing a code block with syntax highlighting. I don’t think that “cxx” has the same strong association with C++.

3 Likes

Quoting @Max_Desiatov from this pull request on SwiftPM:

Usually, CPP is used as an abbreviation for the C preprocessor, while CXX more commonly refers to the C++ compiler.

Also, Clang internally uses the “cxx” prefix when referring to C++ things.

2 Likes

That’s a very specialised use of “usually”, which doesn’t clearly motivate exposing this spelling convention to language users.

2 Likes

FWIW, in macOS and Linux CLI cpp command will launch a C preprocessor, not a C++ compiler.

There's already a precedent for this in public SwiftPM API: CXXSetting type and cxxSettings property of Target, introduced in Swift 5.0. Our users (at least those interested in C++) have already been exposed to this naming convention for more than 3 and a half years.

Either way, I personally would like this thread to stay focused on overall progress with interop. Naming convention discussions, especially those dedicated to a specific API, deserve their own separate thread.

7 Likes

Thanks for the interesting update. As someone who is writing (network protocol) C++ code for microcontrollers which I really would love to reuse from Swift, I wonder about a general rough timeframe. I see that you're working on this since quite a while and though I enjoy the progress updates, I'm not enough "into" the problem to realize how far you really are.

So… for calling a C++ library that is using bits and pieces from STL, how much of an effort is left over until we can just import that like we do with C libraries? Are we talking months, a year, or multiple years?

2 Likes

(post deleted by author)

I cannot provide a specific answer. However, over the next couple of Swift releases we're aiming to be in a position where this becomes possible for a subset of an API surface of any existing C++ library, including parts of STL itself as well.

Right now it's possible to try this feature in an experimental manner, so you could probably import large chunks of the library you're interested in into Swift already. Are you interested in potentially becoming an early adopter so that you could try to see if our current experimental support could work for your use case? That could help us refine the initially supported version of interop as well.

1 Like