Callee's RVO r-value is allocated on caller's stack, thus
std::move a returned r-value and reference to it isn't UB.
https://godbolt.org/z/-CllrO
A NRVO will be allocated on caller's stack as well.
https://godbolt.org/z/iqbhCI
However, if we try to out smart the compiler using std::move for NRVO, compiler has no idea what's inside the std::move thus
create the large object on callee's stack and then do a
memcpy back to caller's stack.
https://godbolt.org/z/ql7B9i
Some UB examples here https://github.com/jeaye/value-category-cheatsheet
is not correct.
Further reading:
https://abseil.io/tips/11
std::move a returned r-value and reference to it isn't UB.
https://godbolt.org/z/-CllrO
#include <utility>
using namespace std;
struct T {
int A[1000];
T()
{
for (int i = 0; i < 1000; i++) {
A[i] = 42;
}
}
};
T layer1()
{
return T{};
}
T layer2()
{
return layer1();
}
T layer3()
{
return layer2();
}
int main()
{
T const &ref{std::move(layer3())};
T &&ref2{std::move(layer3())};
int const &ref3{layer3().A[99]};
int const &ref4{layer3().A[999]};
}
A NRVO will be allocated on caller's stack as well.
https://godbolt.org/z/iqbhCI
#include <utility>
using namespace std;
struct T {
int A[1000];
T()
{
for (int i = 0; i < 1000; i++) {
A[i] = 42;
}
}
};
T layer1()
{
T t{};
return t;
}
int main()
{
int const &ref4{layer1().A[999]};
}
However, if we try to out smart the compiler using std::move for NRVO, compiler has no idea what's inside the std::move thus
create the large object on callee's stack and then do a
memcpy back to caller's stack.
https://godbolt.org/z/ql7B9i
#include <utility>
using namespace std;
struct T {
int A[1000];
T()
{
for (int i = 0; i < 1000; i++) {
A[i] = 42;
}
}
};
T layer1()
{
T t{};
return std::move(t);
}
int main()
{
int const &ref4{layer1().A[999]};
}
Some UB examples here https://github.com/jeaye/value-category-cheatsheet
is not correct.
Further reading:
https://abseil.io/tips/11
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.