I stumbled upon something weird. We all know the taking the address of the return value from a function-call is not allowed - since it's an r-value.
But this seems to be fine:
#include <iostream>
struct Foo {
int val;
Foo* operator &() { // <-- just like normal "&"
return this;
}
};
Foo test() {
return Foo{3};
}
int main() {
Foo* p = &test(); // <-- wtf? allowed and works
printf("%d", p->val);
}
Maybe by overloading the "&"-operator, the return value of first brought into scope of the caller (living on the stack, I guess) and therefore addressable.
Yields deterministic results on (Clang-14 and GCC-12)
Question is: Undefined Behaviour or Legal?
Assembler output clearly shows, that the return value is cached.
[Clang 14.0.0 without arguments]
main: # @main
push rbp
mov rbp, rsp
sub rsp, 16
call test()
mov dword ptr [rbp - 16], eax <---
lea rdi, [rbp - 16] <---
call Foo::operator&()
mov qword ptr [rbp - 8], rax
mov rax, qword ptr [rbp - 8]
mov esi, dword ptr [rax]
movabs rdi, offset .L.str
mov al, 0
call printf
xor eax, eax
add rsp, 16
pop rbp
ret