Does the effect of std::launder last after the expression in which it is called?

126 Views Asked by At

Consider the following sample code:

struct X { const int n; };
union U { X x; float f; };
void fun() {
  U u = {{ 1 }};
  u.f = 5.f;               // OK, creates new subobject of 'u'
  X *p = new (&u.x) X {2}; // OK, creates new subobject of 'u'
  
  if(*std::launder(&u.x.n) == 2){// condition is true because of std::launder
    std::cout << u.x.n << std::endl;  //UB here?
    }
}

What will function fun prints according to the language standard? In other words, does the effect of std::launder last beyond the expression in which it is called? Or, we have to use std::launder each time we need to access the updated value of u.x.n?

1

There are 1 best solutions below

0
On BEST ANSWER

cppereference is quite explicit about it:

std::launder has no effect on its argument. Its return value must be used to access the object. Thus, it's always an error to discard the return value.

As for the standard itself, nowhere does it state that its argument is also laundered (or not), but the signature of the function indicates that in my opinion: the pointer is taken by value, not by reference, thus it cannot be altered in any way visible to the caller.