Calling C++ Functions from Carbon Using the Bridge Mechanism
Learn how to call C++ functions directly from Carbon using its built‑in bridge, with a concrete example, build steps, and a list of current limitations.
14 Jan 2026, 19:31 UTC

Useful answer
You can invoke existing C++ functions directly from Carbon code without writing manual wrappers. The Carbon compiler’s built‑in bridge maps C++ symbols into Carbon’s namespace, preserving the original ABI and letting you call them as if they were native Carbon functions.
How the bridge works – a worked example
Assume you have a simple C++ helper that adds two integers:
// math_utils.cpp
extern "C" int add(int a, int b) {
return a + b;
}
Compile it to an object file (or static library) with a C++ compiler that matches the Carbon toolchain’s target ABI:
# Run in a terminal with a compatible C++ compiler (e.g., clang++)
clang++ -c -o math_utils.o math_utils.cpp
In Carbon you declare the function using an extern "C++" block. The bridge treats the declaration as a direct link to the C++ symbol:
package demo;
// Import the C++ function via the bridge
extern "C++" fn add(a: i32, b: i32) -> i32;
fn main() -> i32 {
let sum = add(7, 5);
print(sum); // Expected output: 12
return 0;
}
Build the Carbon program and link it with the C++ object:
# Assuming the Carbon compiler is `carbonc`
carbonc demo.carbon -o demo math_utils.o
./demo
If the linkage succeeds, the program prints the sum, showing that the C++ function was called directly.
Limits and common mistakes
- Name mangling: The bridge expects the exact mangled name as emitted by the C++ compiler. Using
extern "C"on the C++ side (as in the example) avoids mangling; otherwise you must match the compiler’s mangling scheme. - Templates and inline functions: Only instantiated, non‑template symbols with stable linkage can be bridged. Attempting to bridge a C++ template function without explicit instantiation leads to linker errors.
- ABI compatibility: The Carbon toolchain must target the same architecture, calling convention, and standard library layout as the C++ compilation. Mismatched ABIs cause crashes or silent data corruption.
- Overload resolution: Overloaded C++ functions must be distinguished by their exact signature in the Carbon declaration. Providing a mismatched parameter type results in a "no matching function" error at link time.
- Memory ownership: The bridge does not automatically convert Carbon’s owned types to C++ smart pointers. Passing Carbon-owned objects across the boundary requires manual lifetime management or a custom wrapper.
Practical verification
After building, run the executable and compare the output to the expected value from the C++ function. If the program crashes, check the linker output for unresolved symbols or mismatched mangling, and verify that both the C++ object and Carbon binary were built for the same target triple (e.g., x86_64-linux-gnu).
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.