Skip to content
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

[basic.life]/8 Add a note about pointer to uninitialized memory #5782

Closed
blackteahamburger opened this issue Aug 23, 2022 · 12 comments
Closed

Comments

@blackteahamburger
Copy link
Contributor

Transparently replaceable only applies to objects, so creating an object on uninitialized memory does not automatically make a pointer to the original uninitialized memory point to the newly created object.

Nothing in the standard mentions the above fact. It is recommended to add a note to provide clarity.

@languagelawyer
Copy link
Contributor

What is

a pointer to ... uninitialized memory

@blackteahamburger
Copy link
Contributor Author

blackteahamburger commented Aug 23, 2022

"uninitialized memory" refers to memory that never has any objects on it.

@languagelawyer
Copy link
Contributor

I think we do not have such things because we implicitly create objects. Also, my question was about pointer, not about memory.

@jensmaurer
Copy link
Member

@blackteahamburger , please give a code example.

@blackteahamburger
Copy link
Contributor Author

blackteahamburger commented Aug 24, 2022

I think we do not have such things because we implicitly create objects.

Just call a function that doesn't do IOC:

void* p = __builtin_malloc(1);
new (p) char;
*static_cast<char*>(p) = 'c'; // UB
 __builtin_free(p);

p is a pointer to uninitialized memory.

@jensmaurer
Copy link
Member

@blackteahamburger , this is not a conforming C++ program; its behavior is not specified by the standard. Do you have an example of a conforming program?

@languagelawyer
Copy link
Contributor

Just call a function that doesn't do IOC

IOC functions are not limited to those specified in the standard. Well, ofc, an implementation should define them as IOC, but implementations often ignore the requirement to specify implementation-defined things. I'd say you can treat __builtin_malloc as IOC.

@blackteahamburger
Copy link
Contributor Author

I forgot that IOC do not start the lifetimes of subobjects of such objects that are not themselves of implicit-lifetime types... Just use std::string:

void* p = operator new(sizeof(std::string));    // does not implicitly create a std::string object
std::string* pstr = new (p) std::string;
*static_cast<std::string*>(p) = "str1";    // undefined behavior
*pstr = "str2";    // OK

@languagelawyer
Copy link
Contributor

@blackteahamburger your concern is [basic.life]/8's

after the lifetime of an object has ended

condition, and that the lifetime of the first element of the implicitly-created std::string[1] has never started?

@blackteahamburger
Copy link
Contributor Author

@languagelawyer But I think they are related.
So, where do you think a better place is?

@languagelawyer
Copy link
Contributor

I think the

after the lifetime of an object has ended

condition is slightly misspelled. It does not mean that there necessarily shall be lifetime end, but that if there is lifetime end, it shall be properly synchronized (new object creation shall happen-after the lifetime end).

@tkoeppe
Copy link
Contributor

tkoeppe commented Sep 16, 2022

I'm not sure if there's an editorial issue here. Please reopen if you have a clear improvement in mind.

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

No branches or pull requests

4 participants