(In reply to Jon Coppeard (:jonco) from comment #2) > (In reply to mozillabugs from comment #0) > > as the memory containing `this` is considered reused (and therefore of indeterminate content) upon return from the placement new function and before the new-initializer. > > I don't see how this is using uninitialized storage. The constructor is called before placement new returns so the contents of `this` are not indeterminate. > But placement new does two things: allocate (reuse) memory, and call the constructor. Once it's done its allocation, the memory is considered reused (by which the spec also means uninitialized). From https://eel.is/c++draft/basic.life s.6.7.3(1.5) (the current draft C++ standard): ``` When evaluating a new-expression, storage is considered reused after it is returned from the allocation function, but before the evaluation of the new-initializer ([expr.new]). [Example 1: struct S { int m; }; void f() { S x{1}; new(&x) S(x.m); // undefined behavior } — end example] ```
Bug 1884457 Comment 4 Edit History
Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.
(In reply to Jon Coppeard (:jonco) from comment #2) > (In reply to mozillabugs from comment #0) > > as the memory containing `this` is considered reused (and therefore of indeterminate content) upon return from the placement new function and before the new-initializer. > > I don't see how this is using uninitialized storage. The constructor is called before placement new returns so the contents of `this` are not indeterminate. > But placement new does two things: allocate (reuse) memory, and call the constructor. Once it's done its allocation, the memory is considered reused (by which the spec also means uninitialized). From https://eel.is/c++draft/basic.life s.6.7.3(1.5) (the current draft C++ standard): ``` When evaluating a new-expression, storage is considered reused after it is returned from the allocation function, but before the evaluation of the new-initializer ([expr.new]). [Example 1: struct S { int m; }; void f() { S x{1}; new(&x) S(x.m); // undefined behavior } — end example] ```
(In reply to Jon Coppeard (:jonco) from comment #2) > (In reply to mozillabugs from comment #0) > > as the memory containing `this` is considered reused (and therefore of indeterminate content) upon return from the placement new function and before the new-initializer. > > I don't see how this is using uninitialized storage. The constructor is called before placement new returns so the contents of `this` are not indeterminate. > But placement new does two things: allocate (reuse) memory, and call the constructor. Once it's done its allocation, the memory is considered reused (by which the spec also means uninitialized). From https://eel.is/c++draft/basic.life s.6.7.3(1.5) (the current draft C++ standard): ``` When evaluating a new-expression, storage is considered reused after it is returned from the allocation function, but before the evaluation of the new-initializer ([expr.new]). [Example 1: struct S { int m; }; void f() { S x{1}; new(&x) S(x.m); // undefined behavior } — end example] ```
(In reply to Jon Coppeard (:jonco) from comment #2) > (In reply to mozillabugs from comment #0) > > as the memory containing `this` is considered reused (and therefore of indeterminate content) upon return from the placement new function and before the new-initializer. > > I don't see how this is using uninitialized storage. The constructor is called before placement new returns so the contents of `this` are not indeterminate. > But placement new does two things: allocate (reuse) memory, and call the constructor. Once it's done its allocation, the memory is considered reused (by which the spec also means uninitialized). From https://eel.is/c++draft/basic.life s.6.7.3(1.5) (the current draft C++ standard): ``` When evaluating a new-expression, storage is considered reused after it is returned from the allocation function, but before the evaluation of the new-initializer ([expr.new]). [Example 1: struct S { int m; }; void f() { S x{1}; new(&x) S(x.m); // undefined behavior } — end example] ``` The same thing would happen on self-assignment/move here.