Interoperability failure during bidirectional C++ migration
0 reputation · 09 Sept 2022, 14:48 UTC
0 reputation · 09 Sept 2022, 14:48 UTC
Carbon is designed to allow incremental migration from C++ through bidirectional interoperability. This requires the Carbon compiler to maintain a consistent representation of types and memory layouts when interfacing with existing C++ codebases.
Given the experimental nature of the language, there is uncertainty regarding how the Carbon type system handles complex C++ template instantiations that rely on non-standard compiler extensions or specific ABI behaviors. If the Carbon compiler cannot map a C++ type precisely to its internal representation, the interoperability boundary may fail.
33775 reputation · 09 Sept 2022, 18:52 UTC
As of 2026, Carbon's C++ interoperability is an experimental design goal, not a finished feature. There is no confirmed general mechanism for resolving a C++ template instantiation that exceeds the current mapping capabilities — the design direction is that un-mappable types either fail at compile time or are exposed only through a restricted, opaque view, not silently coerced into a Carbon type. And on the safety question: Carbon's memory-safety invariants stop at the interop boundary. C++ code is treated as unsafe, full stop.
Confirmed: Carbon's interop approach imports C++ declarations through Clang-based parsing and gives them Carbon-facing views. It does not re-implement C++ semantics. The supported subset of C++ declarations is explicitly limited and evolving.
Likely, not confirmed: For a template relying on non-standard compiler extensions or ABI-specific behavior, the expected outcome is a compile-time interop error — Carbon's design philosophy favors explicit failure over silent misinterpretation. Whether a given un-mappable type degrades to an opaque handle today depends on the current toolchain state and must be verified, not assumed. Do not design a migration around an automatic opaque-type fallback existing.
Carbon cannot retroactively apply its safety model to C++ objects. The boundary is a trust boundary:
Treating C++ objects as if they satisfy Carbon invariants reintroduces exactly the memory bugs the migration was meant to eliminate.
Both answers depend on an experimental toolchain that changes frequently. Any claim here about specific fallback behavior or inserted checks should be re-verified against the toolchain revision you actually build; this answer reflects design intent, not shipped guarantees.
Use comments to ask for clarification. Post a solution as an answer.
5,310 reputation · 09 Sept 2022, 15:32 UTC
Carbon’s interop layer is a thin wrapper around the Clang front‑end. When you import a C++ header, Clang parses the declarations and emits an AST that Carbon then consumes. The mapping step is purely structural: each C++ type is examined to see if it can be represented in Carbon’s type system (e.g., built‑in types, POD structs, and simple class hierarchies).
Because Carbon cannot retroactively enforce its safety invariants on raw C++ objects, any pointer or reference that crosses the interop boundary must be treated as unsafe on the Carbon side. A typical pattern is to:
unsafe blocks to access the underlying C++ instance.These steps ensure that the safety guarantees of Carbon are not violated by untrusted C++ code.