We've talked about adding the title to the filename several times over the years and it seems really valuable. This requires us to compute a "slug" for the title spelling that can be part of the filename. Beyond that, we crossed 7000 recently, and so it seems likely that we will need to add digits sooner rather than later here, so this goes ahead and moves us to 6 digits so we don't have to adjust again for a reasonable length of time. To implement this and ensure we can sustain it going forward this adds a tool to our pre-commit that validates (and corrects if needed) the filename. In order to update everything and keep links working, there are a _lot_ of changes, but the most interesting for direct review are in `proposals/scripts`. Assisted-by: Antigravity with Gemini --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
5.3 KiB
C++ Interop: API importing and semantics
Table of contents
Abstract
This proposal defines the concrete technical mechanisms for C++
interoperability. It specifies the precise syntax and semantics for importing
C++ APIs. This includes the import Cpp library "..." and implicitly importing
C++ built-in entities, and the establishment of the Cpp package as the
dedicated namespace for all imported entities.
Problem
While Carbon has a stated goal of seamless C++ interoperability, and a high-level direction has been agreed upon, there is currently no concrete, specified mechanism for developers to actually import and use C++ APIs. This proposal aims to address that by defining the specific syntax and semantics for C++ interoperability.
Background
One of Carbon's primary goals is to be a successor language. This strategy is entirely dependent on seamless, bidirectional interoperability with C++ to enable large-scale adoption and migration for existing C++ codebases.
This proposal provides the necessary details on how C++ APIs should be imported.
Proposal
We propose to formalize the following specific design elements for C++ interoperability:
-
The
CppPackage: All imported C++ entities, whether from built-ins or library headers (see below), will be nested within a dedicatedCpppackage. This prevents name collisions with Carbon code and makes the language boundary explicit.fn UseCppTypes() { // Access C++ types and functions by way of the Cpp package var circle: Cpp.Circle = Cpp.GenerateCircle(); Cpp.PrintCircle(circle); } -
Importing C++ Header-Defined APIs: To import C++ APIs from a specific library header file (for example,
<vector>or"my_library.h"), Carbon code will use theimport Cpp library "..."directive.import Cpp library "<vector>"; import Cpp library "circle.h"; -
Importing C++ Built-in Entities: To access fundamental C++ types (such as
int,bool, etc.), no explicit importing is needed and writingCpp.intandCpp.boolwould just work.
Details
The Cpp package and namespace mapping
All C++ declarations will be imported into the Cpp package. C++ namespaces
will be mapped to nested packages within Cpp. For example, a C++ function
std::string::find would be accessible in Carbon as Cpp.std.string.find. The
C++ global namespace will be mapped to the Cpp package itself. So a function
MyGlobalFunction in the C++ global namespace will be Cpp.MyGlobalFunction in
Carbon.
import Cpp library directive
The import Cpp library "..." directive will instruct the Carbon compiler to
parse the specified C++ header file. The compiler will use the standard C++
include paths to locate the header. Additional paths can be provided through
compiler flags.
The Carbon compiler will leverage a C++ front-end, like Clang, to parse the headers. This ensures a high degree of compatibility with existing C++ code. Only the declarations from the header will be imported, not the definitions (unless they are inline).
C++ built-in types
A set of fundamental C++ types will be available within the Cpp package
without any explicit import directive. Mapping examples:
| C++ Type | Carbon Type |
|---|---|
int |
Cpp.int |
unsigned int |
Cpp.unsigned_int |
double |
Cpp.double |
float |
Cpp.float |
bool |
Cpp.bool |
char |
Cpp.char |
This automatic availability of built-in types is designed to make basic interoperability tasks as smooth as possible.
Rationale
- Code that is easy to read, understand, and write
- Explicitness and Clarity: The
import Cpp library "..."directives make all dependencies on C++ headers. - Preventing Name Collisions: The
Cpppackage is a critical design element. It provides a clean, unambiguous namespace for all imported C++ code.
- Explicitness and Clarity: The
- Interoperability with and migration from existing C++ code
- This proposal defines a foundation for seamless C++ interoperability.
Alternatives considered
- Alternative: Explicitly importing built-ins: We considered making C++
built-in types (like
int) require someimport Cppdirective likeimport Cpp;.- Reason for Rejection: Since
Cppis a special package, it should be implicitly imported, similar to Carbon's prelude.
- Reason for Rejection: Since