Skip to content

Add C.13 to ensure data member lifetimes nest when needed... see #2316#2321

Open
hsutter wants to merge 1 commit intomasterfrom
Add-C.13
Open

Add C.13 to ensure data member lifetimes nest when needed... see #2316#2321
hsutter wants to merge 1 commit intomasterfrom
Add-C.13

Conversation

@hsutter
Copy link
Contributor

@hsutter hsutter commented Mar 5, 2026

Closes #2316


##### Example; bad

This can also come up with concurrency. Ensure that an async operation that access a value is joined before the value it accesses is destroyed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This can also come up with concurrency. Ensure that an async operation that access a value is joined before the value it accesses is destroyed.
This can also come up with concurrency. Ensure that an async operation that accesses a value is joined before the value it accesses is destroyed.

class X {
struct B {
string* p;
explicit B(string& a) : p(&a) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
explicit B(string& a) : p(&a) {}
explicit B(string& a) : p{&a} {}

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es23-prefer-the--initializer-syntax

string a = "some heap allocated string value"; // constructed after b; destroyed before b

public:
X() : b(a) {} // uses a before it is constructed -> use-before-alloc UB
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
X() : b(a) {} // uses a before it is constructed -> use-before-alloc UB
X() : b{a} {} // uses a before it is constructed -> use-before-alloc UB

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es23-prefer-the--initializer-syntax

class X {
struct B {
string* p;
explicit B(string& a) : p(&a) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
explicit B(string& a) : p(&a) {}
explicit B(string& a) : p{&a} {}

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es23-prefer-the--initializer-syntax

B b; // constructed second

public:
X() : b(a) {} // ok
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class X {
public:
X()
: a(std::make_unique<int>(12))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
: a(std::make_unique<int>(12))
: a{std::make_unique<int>(12)}

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es23-prefer-the--initializer-syntax


##### Example; good

This can also come up with concurrency. Ensure that an async operation that access a value is joined before the value it accesses is destroyed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This can also come up with concurrency. Ensure that an async operation that access a value is joined before the value it accesses is destroyed.
This can also come up with concurrency. Ensure that an async operation that accesses a value is joined before the value it accesses is destroyed.

class X {
public:
X()
: a(std::make_unique<int>(12))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
: a(std::make_unique<int>(12))
: a{std::make_unique<int>(12)}

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es23-prefer-the--initializer-syntax

Flag a data member that is `const`, `&`, or `&&` in a type that has any copy or move operation.


### <a name="rc-lifetime"></a>C.13: If one data member uses another, declare it before the other
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My reading of the title is (italic text is mine):

If one data member B uses another data member A, declare it (B) before the other (A)

This is in contrast to what the Discussion section says:

If data member B uses another data member A, then A must be declared before B so that A outlives B

I am not a native English speaker. Is my reading of the title wrong?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with your interpretation of the title and that they contradict.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe title could be 'If one data member uses another, declare it after the used member' ?

Copy link

@rainy-juzixiao rainy-juzixiao Mar 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think maybe it could rephrase to 'Declare a data member before members that depend on it' — it should convey roughly the same meaning?


// Bad: b uses a, but a is declared after b.
// Construction order is b then a; destruction order is a then b.
// So b touches a outside a's lifetime.
Copy link
Contributor

@bgloyer bgloyer Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like the build failed because a's isn't in the dictionary

Copy link

@rainy-juzixiao rainy-juzixiao Mar 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it could also rephrase this line to "So b touches a outside the lifetime of a.", which conveys the same meaning.

I think this phrasing might also express the intent more clearly, I'm not entirely sure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add note to C.30 (or new CP rule) for explicit destructors in classes with concurrency dependencies to prevent UB from member destruction order

5 participants