Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 409
John Z. Li Avatar asked Dec 02 '21 07:12

John Z. Li


1 Answers

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.

like image 60
alagner Avatar answered Oct 04 '22 03:10

alagner