Friday, June 2, 2023

A Vision for Using C++ From Swift

John McCall:

I’m pleased to announce that the Language Steering Group has accepted a vision document entitled Using C++ from Swift.


It is a companion to the previously-accepted vision document Using Swift from C++; together these two visions lay out a technical vision for how Swift can interoperate with C++.

Using C++ from Swift:

Swift’s memory safety is a major feature of its design, and C++’s lack of safety is a major defect. If C++’s unsafety is fully inherited when using C++ APIs from Swift, interoperability will have made Swift a worse language, and it will have undermined one of the reasons to migrate to Swift in the first place. But Swift must also make C++ APIs feel natural to use and fit into Swift’s strong language idioms. Often these goals coincide, because the better Swift understands how a C++ API is meant to be used, the more unsafety and boilerplate it can eliminate from use sites. If the Swift compiler does not understand how to import an API safely or idiomatically, it should decline to import it, requesting more information from the user (likely through the use of annotations) so that the API can be imported in a way that meets Swift’s standards.


Swift should recognize common C++ patterns like ranges (pairs of iterators) and containers and map them into Swift Collections, making them automatically work with Swift’s library of safe and idiomatic collections algorithms. For example, Swift code should be able to filter and map the contents of a std::vector[…]


There are three common patterns for managing reference object lifetimes in C++. Swift should endeavor to support all three of them[…]


Swift will need to decide how to handle projections, and more generally the use of view types, that it doesn’t recognize how to make safe. This may come with difficult trade-offs between usefulness and safety.


Generic code in Swift will not be able to use C++ templates generically without substantial new language features and a lot of implementation work. Allowing C++ templates to be used on concrete Swift types is theoretically more feasible but still a major project because of the ad hoc nature of type constraints in templates. If this feature is ever pursued, it will likely require substantial user guidance through annotations or wrappers around imported APIs.

Using Swift from C++:

For “reverse” interoperability, Swift generates a header that uses C++ language constructs to represent Swift APIs that are exposed by the Swift module. Because of the relatively high expressivity of C++ headers, the generated header is able to provide representation for most native Swift functions, methods, initializers, accessors and types without needing any extra code to be generated in the Swift module. This allows C++ programmers to call into Swift APIs using the familiar C++ function and member function call syntax.


Swift chose to require programs to opt in to Objective-C interoperability with the @objc attribute, both to make export more predictable and to avoid emitting extra code and metadata for all classes. In contrast, as long as the C++ compiler supports the Swift calling convention, a C++ header can call native Swift functions directly, and the C++ type system can be used to wrap most Swift types in a safe C++ representation. Because of this, there is no reason to require Swift module authors to opt in into C++ interoperability. Instead, any Swift module that can be imported into Swift can also be imported into C++, and most APIs will come across automatically.

Some API authors will desire explicit control over the C++ API. Swift will provide an annotation such as the proposed @expose attribute to allow precise control over which APIs get exposed to C++.


The existing Swift to Objective-C bridging layer should still be supported even when C++ bindings are generated in the generated header. Furthermore, the generated C++ bindings should use appropriate Objective-C++ types or constructs in the generated C++ declarations where it makes sense to do so. For instance, a Swift function that returns an Objective-C class instance should be usable from an Objective-C++ compilation unit.


Update (2023-06-09): See also: C++ Interoperability in Swift 5.9.

Update (2023-07-26): See also: Mixing Swift and C++ (Hacker News).

Comments RSS · Twitter · Mastodon

Leave a Comment