C++20 standard "6.7.7 Temporary objects" section states that the expression a = f() requires a temporary object for the result of f(), which is materialized so that the reference parameter of X::operator=(const X&) can bind to it.
That's not the only problem we face in getY for the string example.
std::stringx;x="bugra";
In fact, we have to understand how local variables are initialized. When you create a local integer (int i;), memory is reserved for the new variable, but primitive data types are not default initialized. They will hold whatever value that they find in the allocated memory (on the stack).
On the other hand, std::string is not a primitive data type and objects are default initialized given that they have a default constructor. If they don't have, well, such code wouldn't compile.
classMyClass{public:explicitMyClass(intnum):m_num(num){}private:intm_num;};intmain(){MyClassmc;// ERROR: no matching function for call to 'MyClass::MyClass()'}
So getting back to getY for the string example.
The line std::string x; creates a variable x which is initialized to an empty string. Then on the next line x = "bugra"; you assign a new value to x. x is assigned twice! (The integer i was assigned only once!)
It's yet another problem that "bugra" is not a string. It's a const char* that first have to be - implicitly - converted to a std::string and you pay for it. Hence the immense difference in the ASM code. If we want to avoid that cost, and we have access to C++14, we should use a string literal.
Then the generated ASM code becomes similar:
But even with whatever optimization turned on, there is no reason in similar circumstances to split declaration from initialization. For example, it doesn't let you declare your variables const.
I have some experience in Defence & Aerospace industry. I am mostly interested in swarm robotics. I like to write about C++ language features and best practices.
Just to complement on this part:
That's not the only problem we face in
getY
for the string example.In fact, we have to understand how local variables are initialized. When you create a local integer (
int i;
), memory is reserved for the new variable, but primitive data types are not default initialized. They will hold whatever value that they find in the allocated memory (on the stack).On the other hand,
std::string
is not a primitive data type and objects are default initialized given that they have a default constructor. If they don't have, well, such code wouldn't compile.So getting back to
getY
for the string example.The line
std::string x;
creates a variablex
which is initialized to an empty string. Then on the next linex = "bugra";
you assign a new value tox
.x
is assigned twice! (The integeri
was assigned only once!)It's yet another problem that "bugra" is not a string. It's a
const char*
that first have to be - implicitly - converted to astd::string
and you pay for it. Hence the immense difference in the ASM code. If we want to avoid that cost, and we have access to C++14, we should use a string literal.Then the generated ASM code becomes similar:
But even with whatever optimization turned on, there is no reason in similar circumstances to split declaration from initialization. For example, it doesn't let you declare your variables const.
Here is a great talk on this
Thanks for the great feedback Sandor. I really appreciate it :)