Supported Features and Constraints of C++ Interoperability

Swift supports bidirectional interoperability with C++. This page describes which C++ interoperability features are currently supported. It also talks about the limitations in the current support for C++ interoperability. Additionally, it lists the set of constraints that are related to C++ interoperability support.

C++ interoperability is an actively evolving feature of Swift. Certain aspects of its design and functionality might change in future releases of Swift, as the Swift community gathers feedback from real world adoption of C++ interoperability in mixed Swift and C++ codebases. This page is going to be updated whenever a new release of Swift changes the supported set of C++ interoperability features.

Platform Support

C++ interoperability is supported for development and deployment on all platforms that Swift supports.

Minimum Deployment Version for Mixed-Language Application

C++ interoperability does not impose additional deployment version requirements for your application, except when your Swift code uses C++ classes or structures that become reference types. The minimum deployment version for an application that does not use such reference types is the same as Swift’s regular minimum deployment version.

Minimum Deployment Version for Reference Types Imported from C++

The table below shows the minimum OS version for which a mixed Swift and C++ application that uses C++ classes or structures that become reference types can be deployed. Any deployment platform not listed in the table below is supported automatically, so the imported reference types do not impose addition deployment version requirements for platforms like Ubuntu or CentOS.

Platform running Swift application Minimum deployment version
macOS 13.3
iOS 16.4
watchOS 9.4
tvOS 16.4

Compiler Support

C++ interoperability is supported in Swift 5.9 and above.

Swift’s support for bidirectional interoperability relies on a header generated by the Swift compiler that can then be included by C++ code that wants to use Swift APIs. This header uses Swift-specific compiler extensions that are supported only by the following C++ compilers:

C++ code built with other compilers cannot call Swift functions or use Swift types from C++.

C++ Standard Library Support

Swift compiler uses the platform’s default C++ standard library when interoperating with C++. This table shows which C++ standard library is used when building Swift code for a specific deployment platform:

Platform running Swift application Default C++ Standard Library
Apple platforms libc++
Ubuntu, CentOS, Amazon Linux libstdc++
Windows Microsoft C++ Standard Library (msvcprt)

Swift does not currently support selecting an alternative standard library for platforms that support alternative standard libraries. For example, you can’t use libc++ when building Swift code for Ubuntu, even though libc++ can be used when building C++ code for Ubuntu.

Mixed Swift and C++ code must use the same C++ standard library.

Supported C++ APIs

This section describes which C++ APIs are supported in Swift.

C++ Functions Supported in Swift

Swift supports calling most non-templated:

Functions and constructors that use r-value reference types are not yet available in Swift.

Swift supports calling some C++ function templates. Any function or function template that uses a dependent type in its signature, or a universal reference (T &&) is not available in Swift. Any function template with non-type template parameters is not available in Swift. Variadic function templates are not available in Swift.

A C++ function whose return type is not supported in Swift, or with a parameter whose type is not supported in Swift is not available in Swift.

If a parameter of a C++ function has a default value, the parameter will also have a default value in Swift if:

C++ Types Supported in Swift

The following C++ types can be used in Swift:

C++ types that become value types in Swift can be constructed and passed around by value.

C++ types that become reference types can’t be constructed directly by Swift code. They can be passed around freely between Swift and C++.

C++ types defined inside of a C++ namespace are available in Swift.

Class and structure templates are not directly available in Swift. The instantiated specializations of a class or structure template are available in Swift. Swift code can access template specialization types by using a type alias defined in a C++ header.

Public data members of a C++ structure or class are available in Swift when the type of such data member is supported in Swift.

C++ Standard Library Types Supported in Swift

The following C++ standard library types are supported in Swift:

Other standard library types, like std::unique_ptr, std::function and std::variant are not yet supported in Swift.

Other C++ Features Handled by Swift

C++ Exceptions

Swift can interoperate with C++ code that throws exceptions. However, Swift does not support catching C++ exceptions. Instead, the running program terminates with a fatal error when a C++ exception that’s not caught by C++ code reaches Swift code.

Swift’s strict program termination enforcement for any uncaught exceptions is currently not supported when running Swift code built with Swift on Windows. Any mixed language program running on Windows should always terminate when a C++ exception propagates through Swift code as the program’s stack is unwound. Any attempt to recover from such uncaught exception can lead to undefined behavior in your program.

Clang’s Availability Attributes

C++ APIs annotated with Clang’s availability attributes receive the same availability annotation in Swift.

Supported Swift APIs

This section describes which Swift APIs get exposed to C++ in the generated header.

Swift Structures Supported by C++

Swift can generate C++ representation for most top-level Swift structures. The following Swift structures are not yet supported:

Swift currently does not expose nested structures to C++.

Swift Classes and Actors Supported by C++

Swift can generate C++ representation for most top-level Swift classes and actors. The following Swift classes are not yet supported:

Swift currently does not expose nested classes and actors to C++.

Swift Enumerations Supported by C++

Swift can generate C++ representation for most top-level Swift enumerations that do not have associated values, and some top-level Swift enumerations that have associated values. The following Swift enumerations are not yet supported:

Additionally, the types of all the associated values of an enumeration must be representable in C++. The exact set of representable types is described below, in the section that describes the representable parameter or return types.

Swift currently does not expose nested enumerations to C++.

Swift Functions and Properties Supported by C++

Any function, property, or initializer is exposed to C++ only when Swift can represent all of its parameter and return types in C++. A parameter or return type can be represented in C++ only when:

Functions or initializers that have a parameter type or a return type that’s not listed above cannot be represented in C++ yet. Properties of type that’s not listed above cannot be represented in C++ yet.

Additionally, the following Swift functions, properties and initializers can not yet be represented in C++:

Supported Swift Standard Library Types

Swift is able to represent the following Swift standard library types in C++:

For more details on using Swift types like String in C++, check out the section that describes how to use Swift standard library types from C++.

Note that Swift tuples are not currently supported in C++.

List Of Primitive Swift Types Supported by C++

This table lists the primitive Swift types defined in Swift’s standard library that can be represented in C++:

Swift Type Corresponding C++ type
Bool bool
Int swift::Int
UInt swift::UInt
Int8 int8_t
Int16 int16_t
Int32 int32_t
Int64 int64_t
UInt8 uint8_t
UInt16 uint16_t
UInt32 uint32_t
UInt64 uint64_t
Float float
Double double
Float32 float
Float64 double
CBool bool
CChar char
CWideChar wchar_t
CChar16 char16_t
CChar32 char32_t
CSignedChar signed char
CShort short
CInt int
CLong long
CLongLong long long
CUnsignedChar unsigned char
CUnsignedShort unsigned short
CUnsignedInt unsigned int
CUnsignedLong unsigned long
CUnsignedLongLong unsigned long long
CFloat float
CDouble double

Constraints and Limitations

Swift has some known limitations related to C++ interoperability support. They’re currently listed on GitHub.

Swift Package Manager Constraints

A Swift target that enables C++ interoperability in Swift Package Manager requires its dependencies to enable C++ interoperability as well. A Swift GitHub issue tracks the status of this constraint:

Performance Constraints

Swift’s current support for C++ container types does not provide explicit performance guarantees. Most notably, Swift can make a deep copy of a collection when it’s used in a for-in loop in Swift.

The following issue tracks the status of this performance constraint:

Compatibility with Existing Codebases That Use C or Objective-C APIs in Swift

Enabling C++ interoperability in an existing codebase that imports and uses C or Objective-C APIs in Swift could cause some source breakages in Swift. Even though C++ is largely source compatible with C, there are several cases where C++ diverges. Some common cases of divergences that could cause Swift fail to import C or Objective-C headers in C++ mode are listed below:

In cases like this you’re advised to fix these issues in your C or Objective-C headers. If these headers come from a dependency that you don’t control, you should report an issue to the vendor that vends these headers.

Some existing codebases that use functions from the platform’s C standard library could see ambiguity errors related to such functions being also defined in the C++ standard library. Swift prefers to use math functions like sin and pow from the C standard library. Some other functions that Swift doesn’t know about could still cause an error. In cases where you see such an error related to an ambiguity of a function from the platform’s C standard library you can resolve it by using an explicit module qualifier from Swift when calling such function.