Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions proposals/p6382.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Carbon/C++ Interop: Importing C/C++ object-like macros

<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->

[Pull request](https://github.com/carbon-language/carbon-lang/pull/6382)

<!-- toc -->

## Table of contents

- [Abstract](#abstract)
- [Problem](#problem)
- [Background](#background)
- [Macros in C++](#macros-in-c)
- [Object-like macros](#object-like-macros)
- [Function-like macros](#function-like-macros)
- [Predefined macros](#predefined-macros)
- [Swift / C interop [GitHub][documentation]](#swift--c-interop-githubdocumentation)
- [Proposal](#proposal)
- [Details](#details)
- [Rationale](#rationale)
- [Alternatives considered](#alternatives-considered)

<!-- tocstop -->

## Abstract

This proposal addresses importing object-like C/C++ macros into Carbon.

## Problem

C/C++ object-like macros are used to define constants, conditional compilation,
header guards, etc. and are common for low-level, cross-platform libraries, with
C like APIs. Despite the recommendations for replacing them in C++ with safer
techniques (for example `constexpr`), they remain to be present in C++ code
bases. Of particular interest for the interoperability are cases such as macros
present in the APIs of the standard C++ library (for example error codes in
`<errno.h>`), which can't be easily changed, but remain to be widely used in
low-level C++ libraries. A mechanism for properly importing and handling these
macros is necessary for a seamless interoperability.

## Background

### Macros in C++

Macros are defined with the `#define` directive and processed by the
preprocessor, which replaces the occurrences of the defined identifier with a
replacement-list. There are two types of macros: _object-like_ and
_function-like_ macros. The directive `#undef` undefines a defined macro.

#### Object-like macros

```
#define identifier replacement-list (optional)
```

Replacement-lists can have elements that are:

- Literals: integer, floating-point, string, char, bool etc.
- Non-literal types: structs, classes etc.
- Identifiers: pointing to other macros, variables, types, keywords etc.
- Operators: `+, -, <<, >>, |` etc. to one or more elements.

#### Function-like macros

```
#define identifier(parameters) replacement-list (optional)
#define identifier(parameters, ...) replacement-list (optional)
#define identifier(...) replacement-list (optional)
```

The syntax of function-like macros is similar to the syntax of a function call.
They accept a list of arguments and replace their occurrence in the
replacement-list.

As this is only a text replacement, it can lead to unexpected behaviour if the
arguments are not properly separated with brackets.

In function-like macros, the operators `#` and `##` enable:

- `#operator (stringification)` - the arguments of the macro are converted to
a string literal without expanding the argument. When `#` is used in front
of a parameter in a macro definition (`#param`), the preprocessor replaces
`#param` with the argument tokens as a string literal.

- `##operator (concatenation or token pasting)` - two tokens are merged in a
single token during a macro expansion. For example, when `a##b` is used as
part of the macro definition, the preprocessor merges `a` and `b`, removing
any white spaces in between to form a single token. When some of the tokens
on either side of the `##` operator are parameter names, they are replaced
by the actual argument before the execution of `##`. This is used for
example to create new identifiers like variables, function names etc. and in
general to avoid creating repeated boilerplate code.

#### Predefined macros

There are also predefined macros available in every translation unit. Examples
include: `__cplusplus`, `__FILE__`, `__LINE__`, `__DATE__`, `__TIME__` etc.

### 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)]

Swift supports importing object-like C macros as global constants. Macros that
use integer, floating-point and string literals are supported. Also simple
operators like `+, -, <<, >>` etc. between literals or macros are supported.

Function-like macros are not supported. Instead, using Swift functions and
generics is recommended.

## Proposal

TODO: Briefly and at a high level, how do you propose to solve the problem? Why
will that in fact solve it?

## Details

TODO: Fully explain the details of the proposed solution.

## Rationale

TODO: How does this proposal effectively advance Carbon's goals? Rather than
re-stating the full motivation, this should connect that motivation back to
Carbon's stated goals and principles. This may evolve during review. Use links
to appropriate sections of [`/docs/project/goals.md`](/docs/project/goals.md),
and/or to documents in [`/docs/project/principles`](/docs/project/principles).
For example:

- [Community and culture](/docs/project/goals.md#community-and-culture)
- [Language tools and ecosystem](/docs/project/goals.md#language-tools-and-ecosystem)
- [Performance-critical software](/docs/project/goals.md#performance-critical-software)
- [Software and language evolution](/docs/project/goals.md#software-and-language-evolution)
- [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write)
- [Practical safety and testing mechanisms](/docs/project/goals.md#practical-safety-and-testing-mechanisms)
- [Fast and scalable development](/docs/project/goals.md#fast-and-scalable-development)
- [Modern OS platforms, hardware architectures, and environments](/docs/project/goals.md#modern-os-platforms-hardware-architectures-and-environments)
- [Interoperability with and migration from existing C++ code](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code)

## Alternatives considered

TODO: What alternative solutions have you considered?
Loading