vector
is a struct with two public members X
and Y
; a parameterized constructor that prints integer constructor called
; a copy constructor that prints copy constructor called
; and a move constructor that prints move constructor called <== This line is different\n
.
The function makeVectorx5y5IfNotZero()
returns the vector {5, 5}
if arg
is 0
. otherwise it returns {2, 2}
.
The main
function constructs vector A
using makeVectorx5y5IfNotZero(1)
and constructs vector B
using makeVectorx5y5IfNotZero(0)
.
Here is the code:
#include <iostream>
struct vector{
int X, Y;
vector(int X, int Y) : X(X), Y(Y){
printf("integer constructor called\n");
}
vector(const vector& other): X(other.X), Y(other.Y){
printf("copy constructor called\n");
}
vector(vector&& other): X(other.X), Y(other.Y){
printf("move constructor called <== This line is different\n\n");
}
};
vector makeVectorx5y5IfNotZero(bool Arg){
if(Arg){
vector A(0, 0);
A.X = 5;
A.Y = 5;
return A;
}
else {
vector B(1,1);
B.X = 2;
B.Y = 2;
return B;
}
}
int main(){
printf("Making Vector\n");
vector A = makeVectorx5y5IfNotZero(1);
printf("Made Vector\n");
printf("Making Another Vector\n");
vector B = makeVectorx5y5IfNotZero(0);
printf("Made Vector\n");
}
The output of this code is:
Making Vector
integer constructor called
Made Vector
Making Another Vector
integer constructor called
move constructor called <== This line is different
Made Vector
However, I expected the following output, because of NRVO:
Making Vector
integer constructor called
Made Vector
Making Another Vector
integer constructor called
Made Vector
Why is the local variable B
of makeVectorx5y5IfNotZero()
being moved into the local variable B
of main()
, rather than just constructing a single variable at the same memory address?
Compiler version (output of g++ --version
):
g++ (Rev3, Built by MSYS2 project) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Quoting @PepijnKramer in the comments
It is a gcc limitation (it doesn't optimize the branch)
This discussed more in detail in this video C++ Weekly - Ep 456 - RVO + Trivial Types = Faster Code