---
title: ISO/IEC JTC1/SC22/WG21 White Paper
date: 2026-02-22
reply-to:
  - "Michael Wong <fraggamuffin@gmail.com>"
document: n5036
audience: All of WG21
paper-type: white-paper
---

**Document** **Number:** `5036` **Date:** 2026-02-22 **Reply** **to:** Michael Wong fraggamuffin@gmail.com

# ISO/IEC JTC1/SC22/WG21 White Paper

Contents ii

## 1

1 This document describes requirements for implementations of an interface that computer programs written in the C++ programming language can use to express groups of operations (known as transactions) that appear to execute atomically in relation to other transactions (concurrent or otherwise).

:::wording

2 ISO/IEC 14882:2020 provides important context and specification for this document. This document is written as a set of changes against that specification. Instructions to modify or add paragraphs are written as explicit instructions. Modifications made directly to existing text from ISO/IEC 14882:2020 use <ins>underlining</ins> to represent added text and <del>strikethrough</del> to represent deleted text.

:::

3 This document is non-normative. Some of the functionality described by this document may be considered for standardization in a future version of C++, but it is not currently part of any C++ standard. Some of the functionality in this document may never be standardized, and other functionality may be standardized in a substantially changed form.

4 The goal of this document is to build widespread existing practice for eventually adopting transactional memory in C++.

## Scope

## 2

1 The following referenced document is indispensable for the application of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.

— (1.1) ISO/IEC 14882:2020, *Programming* *Languages* *—* *C++*

2 ISO/IEC 14882:2020 is herein called the C++ Standard. References to clauses within the C++ Standard are written as “C++20 §3.2”.

Normative references 2

## 3

1 No terms and definitions are listed in this document. ISO and IEC maintain terminological databases for use in standardization at the following addresses:

— (1.1) IEC Electropedia: available at https://www.electropedia.org/

— (1.2) ISO Online browsing platform: available at https://www.iso.org/obp

Terms and definitions 3

## 4

### 4.1

1 Conformance requirements for this document are those defined in C++20 §4.1, as applied to a merged document consisting of C++20 amended by this document.

[*Note* *1*: Conformance is defined in terms of the behavior of programs. *— end* *note*]

### 4.2

This work is the result of a collaboration of researchers in industry and academia. We wish to thank the original authors of this document, Michael Wong, Jens Maurer, Hans Boehm, Michael Spear, Michael L. Scott, Victor Luchangco, Maged Michael, and Paul McKenney. We also wish to thank people who made valuable contributions within and outside these groups, including all SG 5 members and the original TM group, and many others not named here who contributed to the discussion.

§ 4.2 4

## 5

### 5.1

:::wording-add

In C++20 §5.10, add <ins>atomic</ins> to the table of identifiers with special meaning (Table 4).

:::

§ 5.1 5

## 6

### 6.9

### 6.9.1

Change in C++20 §6.9.1 paragraph 5 as indicated:

5 A *full-expression* is

— (5.1) ...

:::wording-remove

— (5.2) an invocation of a destructor generated at the end of the lifetime of an object other than a temporary object (6.7.7) whose lifetime has not been extended, <del>or</del>

:::

:::wording-add

— (5.3) <ins>the start or the end of an atomic block (8.8), or</ins>

:::

— (5.4) an expression that is not a subexpression of another expression and that is not otherwise part of a full-expression.

### 6.9.2

**6.9.2.2** **Data** **races** **[intro.races]**

Change in C++20 §6.9.2.2 paragraph 6 as indicated:

:::wording

6 <del>Certain</del> <ins>Atomic blocks as well as certain library calls may synchronize with other atomic blocks</ins> <ins>and</ins> library calls performed by another thread.

:::

Add a new paragraph after C++20 §6.9.2.2 paragraph 20:

:::wording-add

<ins>21</ins> <ins>The execution of an atomic block that is not dynamically nested within another atomic block is</ins> <ins>termed a transaction.</ins>

:::

:::wording-add

<ins>[Note 21: Due to syntactic constraints, blocks cannot overlap unless one is nested within the other.</ins> <ins>— end note]</ins>

:::

:::wording-add

<ins>There is a global total order of execution for all transactions. If, in that total order, a transaction</ins> <ins>T1 is ordered before a transaction T2, then</ins>

:::

:::wording-add

<ins>—</ins> <ins>(21.1)</ins> <ins>no evaluation in T2 happens before any evaluation in T1 and</ins>

:::

:::wording-add

<ins>—</ins> <ins>(21.2)</ins> <ins>if T1 and T2 perform conflicting expression evaluations, then the end of T1 synchronizes</ins> <ins>with the start of T2.</ins>

:::

:::wording-add

<ins>[Note 22: If the evaluations in T1 and T2 do not conflict, they might be executed concurrently. — end</ins> <ins>note]</ins>

:::

:::wording-add

<ins>22</ins> <ins>Two actions are potentially concurrent if ...</ins>

:::

Change in C++20 §6.9.2.2 paragraph 21:

21 ...

:::wording-add

[Note 21: It can be shown that programs that correctly use mutexes<ins>, atomic blocks,</ins> and memory_order::seq_cst operations to prevent all data races and use no other synchronization operations behave as if the operations executed by their constituent threads were simply interleaved, with each value computation of an object being taken from the last side effect on that object in that interleaving. This is normally referred to as "sequential consistency". ... — end note]

:::

Add a new paragraph after C++20 §6.9.2.1 paragraph 21:

:::wording-add

<ins>22</ins> <ins>[Note 22: The following holds for a data-race-free program: If the start of an atomic block T is sequenced</ins> <ins>before an evaluation A, A is sequenced before the end of T, A strongly happens before some evaluation</ins> <ins>B, and B is not sequenced before the end of T, then the end of T strongly happens before B. If an</ins> <ins>evaluation C strongly happens before that evaluation A and C is not sequenced after the start of T, then</ins> <ins>C strongly happens before the start of T. These properties in turn imply that in any simple interleaved</ins>

:::

§ 6.9.2.2 6

:::wording-add

<ins>(sequentially consistent) execution, the operations of each atomic block appear to be contiguous in the</ins> <ins>interleaving. — end note]</ins>

:::

**6.9.2.3** **Forward** **progress** **[intro.progress]**

Change in C++20 §6.9.2.3 paragraph 1 as indicated:

:::wording

1 <del>The implementation may assume that any thread will eventually do</del> <ins>An inter-thread side effect</ins> <ins>is</ins> one of the following:

:::

:::wording

— (1.1) <del>terminate,</del> — (1.2) a call to a library I/O function, — (1.3) an access through a volatile glvalue, or — (1.4) a synchronization operation or an atomic operation <ins>(Clause 31)</ins>.

:::

:::wording-add

<ins>The implementation may assume that any thread will eventually terminate or evaluate an</ins> <ins>inter-thread side effect.</ins>

:::

[*Note* *1*: This is intended to allow compiler transformations such as removal of empty loops, even when termination cannot be proven. *— end* *note*]

§ 6.9.2.3 7

## 8

### 8.1

## 1 Add a production to the grammar in C++20 §8.1 as indicated:

:::wording-add

statement: labeled-statement attribute-specifier-seqopt expression-statement attribute-specifier-seqopt compound-statement attribute-specifier-seqopt selection-statement attribute-specifier-seqopt iteration-statement attribute-specifier-seqopt jump-statement declaration-statement attribute-specifier-seqopt try-block <ins>atomic-statement</ins>

:::

Add a new subclause before C++20 §8.8:

### 8.8

*atomic-statement*: `atomic` `do` *compound-statement*

:::wording-add

<ins>1</ins> <ins>An atomic-statement is also called an atomic block.</ins>

:::

:::wording-add

<ins>2</ins> <ins>The start of the atomic block is immediately after the opening { of the compound-statement.</ins> <ins>Evaluation of the end of the atomic block occurs when the invocation of the destructor for a</ins> <ins>hypothetical automatic variable of class type declared at the start of the atomic block would</ins> <ins>happen (8.7.1).</ins>

:::

:::wording-add

<ins>[Note 1: Thus, variables with automatic storage duration declared in the compound-statement are</ins> <ins>destroyed prior to reaching the end of the atomic block; see 8.7. — end note]</ins>

:::

:::wording-add

<ins>3</ins> <ins>A case or default label appearing within an atomic block shall be associated with a switch</ins> <ins>statement (8.5.3) within the same atomic block. A label (8.2) declared in an atomic block shall</ins> <ins>only be referred to by a statement in the same atomic block.</ins>

:::

:::wording-add

<ins>4</ins> <ins>If the execution of an atomic block evaluates an inter-thread side effect (6.9.2.3) or if an atomic</ins> <ins>block is exited via an exception, the behavior is undefined.</ins>

:::

:::wording-add

<ins>5</ins> <ins>Recommended practice: In case an atomic block is exited via an exception, the program should</ins> <ins>be terminated without invoking a terminate handler (17.9.5) or destroying any objects with static</ins> <ins>or thread storage duration (6.9.3.4).</ins>

:::

:::wording-add

<ins>6</ins> <ins>If the execution of an atomic block evaluates any of the following outside of a manifestly constantevaluated</ins> <ins>context (7.7), the behavior is implementation-defined:</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.1)</ins> an asm-declaration (9.10);

:::

:::wording-add

<ins>—</ins> <ins>(6.2)</ins> <ins>an invocation of a function, unless</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.2.1)</ins> <ins>the function is inline with a reachable definition or</ins> <ins>—</ins> <ins>(6.2.2)</ins> <ins>the function is a library function that may be used in an atomic block 16.4.6.17;</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.3)</ins> <ins>a virtual function call (7.6.1.3);</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.4)</ins> <ins>a function call, unless overload resolution selects</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.4.1)</ins> <ins>a named function (12.4.2.2.2) or</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.4.2)</ins> <ins>a function call operator (12.4.2.2.3), but not a surrogate call function;</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.5)</ins> <ins>a co_await expression (7.6.2.4), a yield-expression (7.6.17), or a co_return statement (8.7.5);</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.6)</ins> <ins>dynamic initialization of a block-scope variable with static storage duration; or</ins>

:::

:::wording-add

<ins>—</ins> <ins>(6.7)</ins> <ins>dynamic initialization of a variable with thread storage duration. [ Note: That includes the</ins> <ins>case when such an initialization is evaluated within an atomic block because the initialization</ins> <ins>was deferred (6.9.3.3). -- end note ]</ins>

:::

§ 8.8 8

:::wording-add

<ins>[Note 2: The implementation can define that the behavior is undefined in some or all of the cases above.</ins> <ins>— end note]</ins>

:::

:::wording-add

<ins>[Example 1:</ins>

:::

:::wording-add

<ins>unsigned int f()</ins> <ins>{</ins> <ins>static unsigned int i = 0;</ins> <ins>atomic do {</ins> <ins>++i;</ins> <ins>return i;</ins> <ins>}</ins> <ins>}</ins>

:::

:::wording-add

<ins>Each invocation of f (even when called from several threads simultaneously) retrieves a unique value</ins> <ins>(ignoring wrap-around). — end example]</ins>

:::

:::wording-add

<ins>[Note 3: Atomic blocks are likely to perform best where they execute quickly and touch little data. — end</ins> <ins>note]</ins>

:::

§ 8.8 9

## 15

### 15.11

Add a row to Table 19 in C++20 §15.11:

Table 19: Feature-test macros

**Macro** **name** **Value** `__cpp_transactional_memory` `202602`

§ 15.11 10

## 16

### 16.4

Add a new subclause after C++20 §16.4.6.16:

:::wording-add

<ins>16.4.6.17</ins> <ins>Functions usable in an atomic block</ins> <ins>[atomic.use]</ins>

:::

:::wording-add

<ins>1</ins> <ins>All library functions may be used in an atomic block (8.8), except</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.1)</ins> <ins>error category objects (19.5.3.5)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.2)</ins> <ins>time zone database (19.5.3.5)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.3)</ins> <ins>clocks (27.7)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.4)</ins> <ins>signal (17.13.5) and raise (17.13.4)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.5)</ins> <ins>set_new_handler, set_terminate, get_new_handler, get_terminate (16.4.5.7, 17.6.4,</ins> <ins>17.9.2)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.6)</ins> <ins>system (17.2.2)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.7)</ins> <ins>startup and termination (17.5) except abort</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.8)</ins> <ins>shared_ptr (20.11.3) and weak_ptr (20.11.4)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.9)</ins> <ins>synchronized_pool_resource (20.12.5)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.10)</ins> <ins>program-wide memory_resource objects (20.12.4)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.11)</ins> <ins>setjmp / longjmp (17.13.3)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.12)</ins> <ins>parallel algorithms (25.3)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.13)</ins> <ins>random_device (26.6.7)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.14)</ins> <ins>locale construction (28.3.1.3)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.15)</ins> <ins>locale::global (28.3.1.6)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.16)</ins> <ins>input/output (Clause 29)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.17)</ins> <ins>atomic operations (Clause 31)</ins>

:::

:::wording-add

<ins>—</ins> <ins>(1.18)</ins> <ins>thread support (Clause 32)</ins>

:::

§ 16.4.6.17 11
