std::launder vs placement-new reachability condition
Asked Answered
F

0

5

std::launder has a precondition that all bytes reachable from the would-be-returned pointer are reachable through the passed pointer.

My understanding is that this is meant to allow compiler optimizations, so that e.g.

struct A {
    int a[2];
    int b;
};

void f(int&);

int g() {
    A a{{0,0},2};
    f(a.a[0]);
    return a.b;
}

can be optimized to always return 2. (see Pointer interconvertibility vs having the same address and Can std::launder be used to convert an object pointer to its enclosing array pointer?)


Does this mean the reachability precondition should also apply to placement-new? Otherwise is there anything preventing me from writing f as follows?:

void f(int& x) {
    new(&x) A{{0,0},0};
}

The address of a.a[0] is the same as that of a and the new A object is transparently replaceable with the old A object, so that a.b in g should now be 0.

Foreleg answered 21/1, 2022 at 20:43 Comment(6)
Yes, looks undefined. But I'm not sure if this optimization is applied in practice, probably not.Matrilineage
Does this mean the reachability precondition should also apply to placement-new? This needs strawpool for voting. But I'd say yes.Shoulder
@LanguageLawyer So right now there is no other rule forbidding it that I am overlooking?Foreleg
@LanguageLawyer If it they are not transparently replaceable, I would assume that return a.b; in g is going to be UB for accessing the member outside the object's lifetime. It wouldn't affect the optimization.Foreleg
@Foreleg ah, I didn't look above fShoulder
I've thought I was only privately thinking about it, but no: groups.google.com/a/isocpp.org/g/std-discussion/c/u5TafpMrNMU/m/…Shoulder

© 2022 - 2024 — McMap. All rights reserved.