Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
lvalues, rvalues, temporary values - peculiar behaviour
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  7 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Simon Parmenter  
View profile  
 More options Oct 2 2012, 7:23 pm
Newsgroups: comp.lang.c++.moderated
From: Simon Parmenter <s...@nospam.invalid>
Date: Tue, 2 Oct 2012 16:23:01 -0700 (PDT)
Local: Tues, Oct 2 2012 7:23 pm
Subject: lvalues, rvalues, temporary values - peculiar behaviour
Hi All

I was just playing around with some test code I had done sometime ago and
found some behaviour I could not explain; looking up the C++11 standard
did me no good either.

It may be the std::string implementation - just guessing here.
So what do you think?

Platform: Ubuntu 12.04 LTS
Compiler: g++ 4.7.2
g++ cmdline: -ggdb -std=c++11 -Wall -Wextra -pedantic -fvisibility=hidden

Here are the code examples:

int main()
{
  std::string s1("Hello");
  std::string s2(" World");

  s1 + s2 = "Eh?";
  std::string  & sr = (s1 + s2 = "Eh?");

  //cout << sr << endl;

  std::string const & sr1(s1 + s2);

  cout << (s1 + s2 = "Eh?") << endl;
  cout << sr << endl;
  cout << sr1 << endl;

}

Output:
Eh?
Hello World
Hello World

int main()
{
  std::string s1("Hello");
  std::string s2(" World");

  s1 + s2 = "Eh?";
  std::string  & sr = (s1 + s2 = "Eh?");

  cout << sr << endl;

  std::string const & sr1(s1 + s2);

  cout << (s1 + s2 = "Eh?") << endl;
  //cout << sr << endl;
  cout << sr1 << endl;

}

Output:
<empty line>
Eh?
Hello World

int main()
{
  std::string s1("Hello");
  std::string s2(" World");

  s1 + s2 = "Eh?";
  std::string  & sr = (s1 + s2 = "Eh?");

  cout << sr << endl;

  std::string const & sr1(s1 + s2);

  cout << (s1 + s2 = "Eh?") << endl;
  cout << sr << endl;
  cout << sr1 << endl;

}

Output:
<empty line>
Eh?
Hello World
Hello World

int main()
{
  std::string s1{"Hello"};
  std::string s2{" World"};

  s1 + s2 = "Eh?";
  std::string const & sr{s1 + s2 = "Eh?"};

  cout << sr << endl;

  std::string const & sr1{s1 + s2};

  cout << (s1 + s2 = "Eh?") << endl;
  cout << sr << endl;
  cout << sr1 << endl;

}

Output:
Eh?
Eh?
Eh?
Hello World

Simon

--

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Francis Glassborow  
View profile  
 More options Oct 3 2012, 12:19 pm
Newsgroups: comp.lang.c++.moderated
From: Francis Glassborow <francis.glassbo...@btinternet.com>
Date: Wed, 3 Oct 2012 09:19:10 -0700 (PDT)
Local: Wed, Oct 3 2012 12:19 pm
Subject: Re: lvalues, rvalues, temporary values - peculiar behaviour
On 03/10/2012 00:23, Simon Parmenter wrote:

> Hi All

> I was just playing around with some test code I had done sometime ago and
> found some behaviour I could not explain; looking up the C++11 standard
> did me no good either.

> It may be the std::string implementation - just guessing here.
> So what do you think?

I think your problem concerns not recognising a library defined operator.

when you wrote:

s1 + s2 = "Eh?";

the compiler sees:

operator=(s1+s2, "Eh?");

It evaluates s1+s2 as a temporary of type std::string and passes that
along with the second argument to the relevant operator=(). Where the
new features of C++11 cut in is in allowing (in this context) a
temporary to be bound to a non-const reference parameter

--
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
SG  
View profile  
 More options Oct 3 2012, 12:22 pm
Newsgroups: comp.lang.c++.moderated
From: SG <s.gesem...@googlemail.com>
Date: Wed, 3 Oct 2012 09:22:31 -0700 (PDT)
Local: Wed, Oct 3 2012 12:22 pm
Subject: Re: lvalues, rvalues, temporary values - peculiar behaviour
{ Please limit your text to fit within 80 columns, preferably around 70,
  so that readers don't have to scroll horizontally to read each line.
  This article has been reformatted manually by the moderator. -mod }

Am Mittwoch, 3. Oktober 2012 01:23:08 UTC+2 schrieb Simon Parmenter:

> Hi All

> I was just playing around with some test code I had done sometime ago and
> found some behaviour I could not explain; looking up the C++11 standard
> did me no good either.

You're invoking undefined behaviour. Simple as that. See my comments
below.

> int main()
> {
>   std::string s1("Hello");
>   std::string s2(" World");
>   s1 + s2 = "Eh?";
>   std::string  & sr = (s1 + s2 = "Eh?");
>   std::string const & sr1(s1 + s2);
>   cout << (s1 + s2 = "Eh?") << endl;
>   cout << sr << endl;
>   cout << sr1 << endl;
> }

sr is a dangling reference. You initialized it to refer to a temporary
object which vanishes soon after that. The assignment operator just reterns
a reference to this object and the compiler loses the information that this
is actually a reference to a temporary (because the function signature
of operator= doesn't say it). So, the temporary life-time extension rule
that applies in the case for sr1 is not applicable to the case sr.

> int main()
> {
>   std::string s1("Hello");
>   std::string s2(" World");
>   s1 + s2 = "Eh?";
>   std::string  & sr = (s1 + s2 = "Eh?");
>   cout << sr << endl;

Same here. sr is a dangling reference. Accessing it invokes undefined
behaviour.

>   std::string const & sr1(s1 + s2);

while for this line a special life-time extension rule kicks in. s1+s2
directly returns a temporary object (and not a reference like the
assignment operator) so the rule applies and the temporary's life-time
is extended to the life-time of the reference sr1.

You might want to check out the following article as well:
http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-imp...

> int main()
> {
>   std::string s1("Hello");
>   std::string s2(" World");
>   s1 + s2 = "Eh?";
>   std::string  & sr = (s1 + s2 = "Eh?");
>   cout << sr << endl;

Once again, undefined behaviour.

> int main()
> {
>   std::string s1{"Hello"};
>   std::string s2{" World"};
>   s1 + s2 = "Eh?";
>   std::string const & sr{s1 + s2 = "Eh?"};
>   cout << sr << endl;

Once again, undefined behaviour.

Cheers!
SG

--
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James K. Lowden  
View profile  
 More options Oct 4 2012, 2:40 pm
Newsgroups: comp.lang.c++.moderated
From: "James K. Lowden" <jklow...@speakeasy.net>
Date: Thu, 4 Oct 2012 11:40:20 -0700 (PDT)
Local: Thurs, Oct 4 2012 2:40 pm
Subject: Re: lvalues, rvalues, temporary values - peculiar behaviour
On Wed,  3 Oct 2012 09:19:10 -0700 (PDT)

Francis Glassborow <francis.glassbo...@btinternet.com> wrote:
> when you wrote:

> s1 + s2 = "Eh?";

> the compiler sees:

> operator=(s1+s2, "Eh?");

Is that right?  Doesn't operator=() still need to be a unary member
function?

Looks to me like s1 + s2 creates a temporary, to which "Eh?" is
assigned.  Anything after that is an accident of implementation.

When I've defined operator+ on my own objects, it returned a const
object, just to prevent this very thing.  I wonder why std::string
doesn't do that.

--jkl

--
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Daniel Krügler  
View profile  
 More options Oct 5 2012, 12:20 am
Newsgroups: comp.lang.c++.moderated
From: Daniel Krügler <daniel.krueg...@googlemail.com>
Date: Thu, 4 Oct 2012 23:15:52 CST
Local: Fri, Oct 5 2012 1:15 am
Subject: Re: lvalues, rvalues, temporary values - peculiar behaviour

Am 04.10.2012 20:40, schrieb James K. Lowden:
[..]

> When I've defined operator+ on my own objects, it returned a const
> object, just to prevent this very thing.  I wonder why std::string
> doesn't do that.

I wouldn't recommend that: Returning const class types in C++11 is
actively preventing moving such rvalues within expressions.

HTH & Greetings from Bremen,

Daniel Krügler

--
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Seungbeom Kim  
View profile  
 More options Oct 6 2012, 2:16 am
Newsgroups: comp.lang.c++.moderated
From: Seungbeom Kim <musip...@bawi.org>
Date: Fri, 5 Oct 2012 23:16:45 -0700 (PDT)
Local: Sat, Oct 6 2012 2:16 am
Subject: Re: lvalues, rvalues, temporary values - peculiar behaviour
On 2012-10-04 11:40, James K. Lowden wrote:

> When I've defined operator+ on my own objects, it returned a const
> object, just to prevent this very thing.  I wonder why std::string
> doesn't do that.

Because no one would write 's1 + s2 = "Eh?"' and expect the result of
the assignment to be found later in any variable? (It's different from
the situation in 'void incr(double&); int i; incr(i);' where there
would be people expecting the side effect to be observed in i later.)

It also prevents usage patterns like 'f((s1+s2).replace(...).substr(...))'
which can be useful sometimes.

--
Seungbeom Kim

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gene Bushuyev  
View profile  
 More options Oct 6 2012, 2:30 am
Newsgroups: comp.lang.c++.moderated
From: Gene Bushuyev <publicfil...@gbresearch.com>
Date: Fri, 5 Oct 2012 23:30:50 -0700 (PDT)
Local: Sat, Oct 6 2012 2:30 am
Subject: Re: lvalues, rvalues, temporary values - peculiar behaviour

On Thursday, October 4, 2012 11:40:30 AM UTC-7, James K. Lowden wrote:
> On Wed,  3 Oct 2012 09:19:10 -0700 (PDT)
...
> When I've defined operator+ on my own objects, it returned a const
> object, just to prevent this very thing.  I wonder why std::string
> doesn't do that.

That's not a good solution, as it was mentioned, it would hurt
performance by prohibiting moving temporaries.  I think the right
solution is to supply correct ref-qualifier to the declaration of
operator=

basic_string& operator= (basic_string other) &
{
    /*move guts from other*/;
    return *this;

}

I wonder why the standard instead specifies these two overloads:
basic_string& operator=(const basic_string& str); basic_string&
operator=(basic_string&& str) noexcept;

--
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »