-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Carbon/C++ Interop: Primitive Types proposal #5448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Carbon/C++ Interop: Primitive Types proposal #5448
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good to me, I think the conversions align. Looking through this did make me realize I'd missed the Core.Cpp
naming -- sorry about that.
proposals/p5448.md
Outdated
- Carbon `iN` types will map to C++ `intN_t` types (for example `i32` -> | ||
`int32_t`). | ||
- `long`, `long long` in C++ will map to new Carbon types (for example | ||
`Core.Cpp.long/long_long`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zygoloid What was your intent for where long
falls? I'd been assuming Cpp.long
, and missed that the design was writing Core.Cpp.long
until now. I think there are some behavioral trade-offs:
- If it's in a non-prelude
Core
library, it's presumably implicitly imported whenimport Cpp
is written, but not added to name lookup. I think this would require some work on import boundaries. - If it's in the prelude, then we're privileging a C++ type in a way that we might not want to echo for other programming languages (or even other C++ types).
- If it's in a
Cpp
-packaged library implemented in Carbon code, then we might need some special-casing to allowpackage Cpp
, but it could behave similar toexport import
for a user. - If it's treated similar to other C++ types, it could just be added every time
import Cpp
is processed. So it's stillCpp.long
, and conversions to Carbon types work, but it's still a little special because that's not how most C++ types work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per discussion in the interop meeting and separate discussion with @chandlerc, I think our preference here is Cpp.long
, Cpp.long_long
, and so on. I don't think we've explicitly discussed keyword order, but I'm assuming it's:
Cpp.[unsigned_](long_long|long|int|short|double|float)
That is: signedness, then size keyword(s), then a type keyword only if there were no size keywords. (So unsigned_int
not unsigned
, long
not long_int
.)
Some mention of why we think it's OK to do this despite the risk of name collisions would be great to include in this proposal.
We should include in "Alternatives considered" at least three other options:
- Allow all keyword permutations. Reason not to do this: it's unnecessary and complicated.
- Only include the keywords, and provide some syntax for combining them (eg,
Cpp.unsigned & Cpp.long
orCpp.unsigned(Cpp.long)
). Reason to do this: avoids taking any identifiers fromCpp
that are not C++ keywords. Reason not to do this: overly complicated. - Use
Core.Cpp.blah
instead ofCpp.blah
. Reason to do this: avoid name collisions with C++ code. Reason not to do this: we don't think the name collisions are a problem in practice, and would prefer to keep C++-specific stuff in packageCpp
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Done.
- `f16`, `f32`, and `f64` - always available | ||
- `f80`, `f128`, or `f256` may be available, depending on the platform | ||
|
||
### C++ Fundamental Types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps let's improve consistency on how we write platform specific notes.
I suggest:
<Platform>: definition
Other: definition
Also, I don't think we need to mention that LP32 is not Carbon supported several times, we can have it as a note at the beginning or at the end, and clarify that for now we're considering this platform as not supported.
If you say it in the beginning, you can also decide to just ignore it in the table, so it might be useful to have that information (perhaps you can move it to a different place).
|
||
**Standard floating-point types** | ||
|
||
| Type | Format | Width in bits | Note | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add links to the specific formats.
[LP64](/proposals/p5448.md#data-models)). Historic platforms like | ||
[LP32](/proposals/p5448.md#data-models) won't be supported. | ||
|
||
## Proposal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we say explicitly that if C++ considered two types to be different types, Carbon would treat them as different types as well?
I see you write it below, but you can put it above instead to clarify this guides the mapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
proposals/p5448.md
Outdated
| `Core.Cpp.unsigned_long` | `unsigned long`, [LP64](/proposals/p5448.md#data-models): `uint_fast64_t`, `uint_least64_t`, `uintmax_t`, `uintptr_t`, `size_t` | | ||
| `Core.Cpp.unsigned_long_long` | `unsigned long long`, [LLP64](/proposals/p5448.md#data-models): `uint_fast64_t`, `uint_least64_t`, `uintmax_t` | | ||
| `Core.Cpp.long_double` | `long double` | | ||
| X (No mapping) | `float32_t`, `float64_t`, `bfloat16_t` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably map them eventually, why not TBD?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
proposals/p5448.md
Outdated
- Carbon `iN` types will map to C++ `intN_t` types (for example `i32` -> | ||
`int32_t`). | ||
- `long`, `long long` in C++ will map to new Carbon types (for example | ||
`Core.Cpp.long/long_long`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per discussion in the interop meeting and separate discussion with @chandlerc, I think our preference here is Cpp.long
, Cpp.long_long
, and so on. I don't think we've explicitly discussed keyword order, but I'm assuming it's:
Cpp.[unsigned_](long_long|long|int|short|double|float)
That is: signedness, then size keyword(s), then a type keyword only if there were no size keywords. (So unsigned_int
not unsigned
, long
not long_int
.)
Some mention of why we think it's OK to do this despite the risk of name collisions would be great to include in this proposal.
We should include in "Alternatives considered" at least three other options:
- Allow all keyword permutations. Reason not to do this: it's unnecessary and complicated.
- Only include the keywords, and provide some syntax for combining them (eg,
Cpp.unsigned & Cpp.long
orCpp.unsigned(Cpp.long)
). Reason to do this: avoids taking any identifiers fromCpp
that are not C++ keywords. Reason not to do this: overly complicated. - Use
Core.Cpp.blah
instead ofCpp.blah
. Reason to do this: avoid name collisions with C++ code. Reason not to do this: we don't think the name collisions are a problem in practice, and would prefer to keep C++-specific stuff in packageCpp
.
proposals/p5448.md
Outdated
| `Core.Cpp.long` | `long`, [LP64](/proposals/p5448.md#data-models): `int_fast64_t`, `int_least64_t`, `intmax_t`, `intptr_t`, `ptrdiff_t` | | ||
| `Core.Cpp.long_long` | `long long`, [LLP64](/proposals/p5448.md#data-models): `int_fast64_t`, `int_least64_t`, `intmax_t` | | ||
| `Core.Cpp.unsigned_long` | `unsigned long`, [LP64](/proposals/p5448.md#data-models): `uint_fast64_t`, `uint_least64_t`, `uintmax_t`, `uintptr_t`, `size_t` | | ||
| `Core.Cpp.unsigned_long_long` | `unsigned long long`, [LLP64](/proposals/p5448.md#data-models): `uint_fast64_t`, `uint_least64_t`, `uintmax_t` | | ||
| `Core.Cpp.long_double` | `long double` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we add just these five [Core.]Cpp.something
types, or all the C++ types, including the ones with an effectively fixed mapping? It'd be more consistent to add them all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added them all, PTAL.
proposals/p5448.md
Outdated
- `Core.Cpp.long`: either 32-bit or 64-bit, and use an appropriate int | ||
type that is compatible with (but different) from `i32`/`i64`. | ||
- `Core.Cpp.long_long`: a platform dependent alias to `i64`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not completely clear to me what model is being proposed here. I think the main options are:
Cpp.long
andCpp.long_long
both map to Carbon types that are distinct fromiN
for anyN
, but are compatible with eitheri32
ori64
as appropriate.- If
int64_t
islong
thenCpp.long
isi64
and ifint64_t
islong long
thenCpp.long_long
isi64
. Whichever types don't map toiN
are distinct Carbon types that are compatible withiN
instead. int
,long
, andlong long
all map to one ofi32
ori64
. This means two different C++ types map to the same Carbon type.
Your alternatives considered says why we're not doing option 3. But I think we should also consider whether we want option 1 or option 2. I think the description in this proposal is saying we'd do option 1, but we'd at least previously been talking about doing option 2 instead. That seems to be a reasonable rule that can be described without explicitly treating long
and long long
as special cases:
intN_t
in C++ is always the same type asiN
in Carbon. And likewise foruintN_t
/uN
.builtin type
in C++ is always the same type asCpp.builtin_type
in Carbon for some specified set ofbuiltin type
s.- As a consequence, builtin types in C++ that aren't the same as
intN_t
oruintN_t
for anyN
end up being nameable in Carbon only asCpp.builtin_type
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I updated the proposal to reflect on these comments, PTAL.
proposals/p5448.md
Outdated
Carbon won't have aliases or distinct types for `int_fastN_t`, `int_leastN_t`, | ||
`intmax_t`, `intptr_t`, `ptrdiff_t`, `size_t`. This may be reconsidered in the | ||
future if need arises. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth pointing out that Cpp.size_t
etc will exist if the C++ header declaring the typedef is imported, so we don't need any explicit support for these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I updated the Proposal, Details and Alternatives sections to reflect on the comments. Will go later through the comments on the Background section. |
A proposal for Primitive Types mapping between Carbon and C++.
Part of #5263