# Returning An Std::pair, Std::unique_ptr&> From A Function Results In Weirdness

## 10 February 2022 - 1 answer

I'm having trouble understanding the (to me intricate) mechanisms executed behind the scenes in the following code example:

#include <utility>
#include <memory>
#include <iostream>

struct A {int a;};
struct B {int b;};

std::pair<std::shared_ptr<A>, std::unique_ptr<B>&> FuncA() {
std::shared_ptr<A> a = std::make_shared<A>();
std::unique_ptr<B> b = std::make_unique<B>();

a->a = 12; b->b = 13;

std::cout << "FuncA a: " << a.get() << std::endl;
std::cout << "FuncA b: " << b.get() << std::endl;

std::cout << "FuncA a.a: " << a->a << std::endl;
std::cout << "FuncA b.b: " << b->b << std::endl;

return {a,b};
}

void FuncC(std::pair<std::shared_ptr<A>, std::unique_ptr<B>&> input) {
std::cout << "FuncC a: " << input.first.get()  << std::endl;
std::cout << "FuncC b: " << input.second.get() << std::endl;

std::cout << "FuncC a.a: " << input.first->a  << std::endl;
std::cout << "FuncC b.b: " << input.second->b << std::endl;
}

void FuncB() {
auto ret = FuncA();

std::cout << "FuncB a: " << ret.first.get()  << std::endl;
std::cout << "FuncB b: " << ret.second.get() << std::endl;

std::cout << "FuncC a.a: " << ret.first->a  << std::endl;
std::cout << "FuncC b.b: " << ret.second->b << std::endl;

FuncC(ret);
}

int main(){
FuncB();
}

I've compiled the code with both GCC and Clang which give similar results:

FuncA a: 0xfeaec0
FuncA b: 0xfeaed0
FuncA a.a: 12
FuncA b.b: 13
FuncB a: 0xfeaec0
FuncB b: 0x7ffd1c8e4a00
FuncC a.a: 12
FuncC b.b: 479087264
FuncC a: 0xfeaec0
FuncC b: 0x406100
FuncC a.a: 12
FuncC b.b: 1449378512

As is clearly visible, the address of the std::unique_pointer reference (and of course also its value) are not the same as within FuncA, but the address and value of the std::shared_pointer are unchanged.

What's happening here, and what (if anything) could be done to make the reference-passing correct?

Is some form of copy-constructor being executed on the std::unique_ptr as a result of returning from FuncA?