I have the following code:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
string &s1 = argv[0]; // error
const string &s2 = argv[0]; // ok
argv[0] = "abc";
cout << argv[0] << endl; // prints "abc"
cout << s2 << endl; // prints program name
}
I receive the following error for s1
:
invalid initialization of reference of type 'std::string& {aka std::basic_string<char>&}' from expression of type 'char*'
Then why does the compiler accept s2
?
Interestingly, when I assign a new value to argv[0]
then s2
does not change. Does the compiler ignore that it's a reference and copies the value anyway? Why does it happen?
I write this in Code::Blocks 16.01 (mingw). The same happens with/without -std=c++11
.
Then why does the compiler accept s2?
Because a constant reference can bind to a temporary, and std::string
has a constructor that can take a char *
for a parameter.
That assignment constructs a so-called "temporary" object, and binds a constant reference to it.
Interestingly, when I assign a new value to argv[0] then s2 does not change.
Why should it change? s2
is a separate object. A std::string
object does not maintain a pointer to a char *
that created it. There are many ways to create a std::string
. The actual string is owned by the object. If the std::string
is constructed from a literal character string, it gets copied into the std::string
. So, if the literal character string comes from a buffer, and the buffer is subsequently modified, it has no effect on the std::string
.
This line:
const string &s2 = argv[0];
Creates a new string
instance, copying the contents of argv[0]
, and binds the reference to it. Later, this copy is outputted, which is now unrelated to the actual value of argv[0]
.
The temporary string objects lifetime, created in the quoted line, is expanded to the scope of the block, because a const reference was formed to it. See more at: Does a const reference prolong the life of a temporary?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With