Skip to content

Commit dceaa26

Browse files
Fill in Problem and Background sections
1 parent e45b6b6 commit dceaa26

File tree

1 file changed

+79
-6
lines changed

1 file changed

+79
-6
lines changed

proposals/p6382.md

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
1515
- [Abstract](#abstract)
1616
- [Problem](#problem)
1717
- [Background](#background)
18+
- [Macros in C++](#macros-in-c)
19+
- [Object-like macros](#object-like-macros)
20+
- [Function-like macros](#function-like-macros)
21+
- [Predefined macros](#predefined-macros)
22+
- [Swift / C interop [GitHub][documentation]](#swift--c-interop-githubdocumentation)
1823
- [Proposal](#proposal)
1924
- [Details](#details)
2025
- [Rationale](#rationale)
@@ -24,18 +29,86 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2429

2530
## Abstract
2631

27-
TODO: Describe, in a succinct paragraph, the gist of this document. This
28-
paragraph should be reproduced verbatim in the PR summary.
32+
This proposal addresses importing object-like C/C++ macros into Carbon.
2933

3034
## Problem
3135

32-
TODO: What problem are you trying to solve? How important is that problem? Who
33-
is impacted by it?
36+
C/C++ object-like macros are used to define constants, conditional compilation,
37+
header guards, etc. and are common for low-level, cross-platform libraries, with
38+
C like APIs. Despite the recommendations for replacing them in C++ with safer
39+
techniques (for example `constexpr`), they remain to be present in C++ code
40+
bases. Of particular interest for the interoperability are cases such as macros
41+
present in the APIs of the standard C++ library (for example error codes in
42+
`<errno.h>`), which can't be easily changed, but remain to be widely used in
43+
low-level C++ libraries. A mechanism for properly importing and handling these
44+
macros is necessary for a seamless interoperability.
3445

3546
## Background
3647

37-
TODO: Is there any background that readers should consider to fully understand
38-
this problem and your approach to solving it?
48+
### Macros in C++
49+
50+
Macros are defined with the `#define` directive and processed by the
51+
preprocessor, which replaces the occurrences of the defined identifier with a
52+
replacement-list. There are two types of macros: _object-like_ and
53+
_function-like_ macros. The directive `#undef` undefines a defined macro.
54+
55+
#### Object-like macros
56+
57+
```
58+
#define identifier replacement-list (optional)
59+
```
60+
61+
Replacement-lists can have elements that are:
62+
63+
- Literals: integer, floating-point, string, char, bool etc.
64+
- Non-literal types: structs, classes etc.
65+
- Identifiers: pointing to other macros, variables, types, keywords etc.
66+
- Operators: `+, -, <<, >>, |` etc. to one or more elements.
67+
68+
#### Function-like macros
69+
70+
```
71+
#define identifier(parameters) replacement-list (optional)
72+
#define identifier(parameters, ...) replacement-list (optional)
73+
#define identifier(...) replacement-list (optional)
74+
```
75+
76+
The syntax of function-like macros is similar to the syntax of a function call.
77+
They accept a list of arguments and replace their occurrence in the
78+
replacement-list.
79+
80+
As this is only a text replacement, it can lead to unexpected behaviour if the
81+
arguments are not properly separated with brackets.
82+
83+
In function-like macros, the operators `#` and `##` enable:
84+
85+
- `#operator (stringification)` - the arguments of the macro are converted to
86+
a string literal without expanding the argument. When `#` is used in front
87+
of a parameter in a macro definition (`#param`), the preprocessor replaces
88+
`#param` with the argument tokens as a string literal.
89+
90+
- `##operator (concatenation or token pasting)` - two tokens are merged in a
91+
single token during a macro expansion. For example, when `a##b` is used as
92+
part of the macro definition, the preprocessor merges `a` and `b`, removing
93+
any white spaces in between to form a single token. When some of the tokens
94+
on either side of the `##` operator are parameter names, they are replaced
95+
by the actual argument before the execution of `##`. This is used for
96+
example to create new identifiers like variables, function names etc. and in
97+
general to avoid creating repeated boilerplate code.
98+
99+
#### Predefined macros
100+
101+
There are also predefined macros available in every translation unit. Examples
102+
include: `__cplusplus`, `__FILE__`, `__LINE__`, `__DATE__`, `__TIME__` etc.
103+
104+
### Swift / C interop [[GitHub](https://github.com/swiftlang/swift/blob/main/lib/ClangImporter/ImportMacro.cpp)][[documentation](https://developer.apple.com/documentation/swift/using-imported-c-macros-in-swift)]
105+
106+
Swift supports importing object-like C macros as global constants. Macros that
107+
use integer, floating-point and string literals are supported. Also simple
108+
operators like `+, -, <<, >>` etc. between literals or macros are supported.
109+
110+
Function-like macros are not supported. Instead, using Swift functions and
111+
generics is recommended.
39112

40113
## Proposal
41114

0 commit comments

Comments
 (0)