C++ Interop workgroup meeting notes (Mar 14th 2022)

This post contains the summarized meeting notes from the Swift and C++ interoperability workgroup sync-up meeting from the 14th of March.

Attendees: compnerd, Alex_L, richard, dabrahams, zoecarver, cabmeurer, 0x41c, bro4all, bulbazord, drodriguez, degoo, mikepinkerton, egor.zhdan, NuriAmari, vpadmnabh


Discussed degoo’s question related to out-of-date ABI docs (swift/TypeMetadata.rst at main · apple/swift · GitHub), which could be important in the context of reverse interoperability. Alex_L described the approach that Swift will take for reverse interop - it will use its intrinsic ABI knowledge in the compiler and will emit the right interface that matches the ABI from the compiler. Outdated documentation is still an issue though. Zoecarver suggested to degoo to ask this question about outdated ABI docs on the Swift forums to get direct response from the ABI experts on the forums. 0x41c mentioned that a reflection library called Echo (GitHub - Azoy/Echo: A complete reflection library for Swift) is able to go through the type descriptors correctly without any ABI issues, and mentioned that the library’s author can provide some insight into this and that they’re often active on the forums as well.

Next we re-visited the topic of documentation.

  • Alex_L: status page is ready to post, will merge it today (Merged to swift/CppInteroperabilityStatus.md at main · apple/swift · GitHub). Status page describes which C++ language and standard library features have experimental support for being bridged over and used from Swift.
  • Alex_L: we’re going to be working on the vision doc next. If you have ideas or specific points you want to see covered, please add them to the document.

Alex_L also had a question about getting started with C++ interop docs (swift/GettingStartedWithC++Interop.md at main · apple/swift · GitHub). There’s a SwiftPM section in that document, and it looks like it could just work without issues. Now that compnerd’s fix for using clang++ from Swift driver has landed, are there any other things that should be done to improve SwiftPM support?

  • compnerd: haven’t tested on Windows, but there could still be issues with regards to selection of a C++ runtime (from Swift driver). There’s Microsoft c++ runtime, GNU c++ runtime, and libc++ runtime. These choices should cover it for now. We ought to make sure that all 3 of those work. We need to expose a flag to select between them. Also there’s still an issue of some search paths being added implicitly.
  • richard had some concerns about the settings in the SwiftPM package in the getting started guide (swift/GettingStartedWithC++Interop.md at main · apple/swift · GitHub). The unsafe flags are problematic for non-leaf packages, as they prevent SwiftPM from resolving a package dependency that uses unsafe flags.
  • compnerd suggested the following idea to address the unsafe flags problem: take the same strategy that was used with concurrency and differential programming - when a C++ standard library module gets imported, Swift should automatically add the enable-cxx-interop flag to its compilation.
  • zoecarver: there could be some challenges. Concurrency was something we wanted to enable by default. We don’t know if we want to enable C++ interop by default yet. Having to use a flag might not be a bad thing.
  • compnerd: we can know if we need to enable interop by looking at the module map, as that will have to have a requires cplusplus clause in it.
  • zoecarver: bridging header could still be an issue. Also this could be bad for incremental compilation. It might make sense to separate out the configuration of the project and its build. This kind of approach could work well for testing, but there could then be a weird transition period for early adopters who rely on that if it stops working in the future.
  • 0x41c confirmed the issue with resolving package dependency that uses unsafe flags still exists. SwiftPM cancels the resolution of dependencies in that case.
  • richard: the example in the doc worked because it’s an executable target in a leaf package, so it’s not a dependency for something else.
  • Alex_L: we should revisit this as it seems that this calls for a slightly different discussion (as pointed out by compnerd earlier). We ought to discuss whether interop should be enabled by default and how, even outside of Swift PM. That might need to be answered first before we make specific SwiftPM decisions.

Lastly we discussed how the C++ standard library module name and namespace name should be imported into Swift.

  • Alex_L: Right now C++ standard library is imported using the std module name and std namespace qualifier in Swift itself. Not very descriptive. Original interop manifesto proposed cxx_std. We could also adopt CxxStdlib to match the proposed CStdlib module (Pitch: The CStdlib module).
  • richard: Can the C++ APIs be imported without the std prefix?
  • dabrahams: You'd have to do something special to keep it from acting differently from to make it act differently from a regular swift module. It’s available without the std module qualification already (but the namespace is still there).
  • 0x41c: Could we have something like import Stdlib.Cxx?
  • drodriguez: Is this a valid syntax?
  • compnerd: It’s valid. However, there’s a problem - you will need a single module map for the system as that will need to be a sub module in that module map.
  • dabrahams: I don't think it's worth going to a lot of trouble to try and stack up these name spaces. That'll just make it harder to do a qualified name lookup.
  • zoecarver: The more that we can try to not do something different than what the default behavior is, the better. There are a lot of standard library vendors, and embedded projects might have what they consider their standard library. Standard library is designed to be isolated from the compiler. If we can do something that can be applied to any library the easier it is for custom standard libraries.
  • compnerd: CxxStdlib works rather well and is consistent with CStdlib. Also, the standard library is definitely not isolated from the compiler in many cases. in C++ it's very much fairly intertwined with the compiler and it uses a lot of extensions that are compiler specific to actually get reasonable code gen.
  • dabrahams: Shouldn’t spend too much time on this. I have some serious doubts that it will be good for Swift and for C++ interop if we transform C++ names. I work for a company that’s got many tens of millions of lines of C++. If we want Swift to start taking over, it’s going to have to be comfortable for our C++ developers, so that they can identify things that they’re used to using from C++. If we start making this stuff look like Swift components, it’s going to be harder for them to get into that.
  • compnerd: Going back to the original point of trying to stick with the defaults of Swift. We can look at how C code is imported into Swift. It doesn't actually change very much, except in specific cases where it's either a particular API, which is annotated directly or with API notes, but in general it’s 1 to 1 mapping.
  • dabrahams: Yeah, I very much agree with that. I think having things look different might be a good idea. Then the properties of Swift types and C++ types can be different which could be a good signal that you’re in unsafe land here. I'm not objecting to manual enhancement of APIs to make them more Swifty. What I'm talking about is automated transformation of identifiers into other things, that doesn’t seem like a good idea, and also a distraction for us (the workgroup).
  • zoecarver: Yeah there's definitely more low hanging fruit that's more important. I agree with that. In addition to importing 1 to 1 APIs, would it also make more sense to invest in refactoring tools, especially that work across languages, so that companies can refactor their codebases. Maybe there could be a refactoring tool to refactor getters and setters into properties, rather than doing that automatically.
  • Alex_L: out of time, to be continued in the next meeting.