I have tried some compilers and some C++ standard versions. This code may have a deadlock (the comments point out that this is UB) and can be reproduced at least under gcc8 and C++11. I use "Compiler Explorer" to check out the assembly of this code. And I find that the argument q
of function foo1
is not dropped until the caller statement in main
ends.
https://godbolt.org/z/vaes53z44
#include <iostream>
#include <memory>
#include <mutex>
std::mutex mtx;
int foo1(std::unique_lock<std::mutex> q) {
std::cout << "foo1" << std::endl;
return 0;
}
void foo2(int _v) {
std::unique_lock<std::mutex> q(mtx);
std::cout << "foo2" << std::endl;
}
int main() {
foo2(foo1(std::unique_lock<std::mutex>(mtx)));
return 0;
}
Yes, parameters may live until the end of the enclosing full-expression. In this case, the full-expression is foo2(foo1(std::unique_lock<std::mutex>(mtx)))
.
[expr.call]/6, emphasis mine:
It is implementation-defined whether a parameter is destroyed when the function in which it is defined exits or at the end of the enclosing full-expression; parameters are always destroyed in the reverse order of their construction.