[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-26 Thread thiago at kde dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #14 from Thiago Macieira thiago at kde dot org 2013-04-26 
06:16:04 UTC ---

Understood. The idea is that one would write:



  QString str = QString(%1 %2).arg(42).arg(43);


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-26 Thread redi at gcc dot gnu.org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #15 from Jonathan Wakely redi at gcc dot gnu.org 2013-04-26 
08:12:36 UTC ---

That will also work if you return an rvalue, not an rvalue reference, and will

be safe against accidental misuse.


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-26 Thread thiago at kde dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #16 from Thiago Macieira thiago at kde dot org 2013-04-26 
13:45:35 UTC ---

Thanks for the hint.



However, returning an rvalue, even if moved-onto, will generate code for the

destructor. It's not a matter of efficiency, just of code size.



Anyway, I'll do some benchmarks, after I figure out how to work around the

binary compatibility break imposed by having the  in the function that already

existed.


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread glisse at gcc dot gnu.org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #4 from Marc Glisse glisse at gcc dot gnu.org 2013-04-25 06:19:35 
UTC ---

(In reply to comment #0)

 Now suppose the following function:

 

 void g(A a)

 {

 a.p();

 }

 

 Which overload should GCC call? This is my request for clarification. I

 couldn't find anything specific in the standard that would help explain one 
 way

 or the other.

 

 Intuitively, it would be the rvalue overload, but gcc calls the lvalue 
 overload

 instead.



As you note in a further comment, a named rvalue reference acts as an lvalue.



 Making it:

 

 std::move(a).p();

 

 Does not help.



It does for me...


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread glisse at gcc dot gnu.org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #5 from Marc Glisse glisse at gcc dot gnu.org 2013-04-25 06:34:03 
UTC ---

(In reply to comment #4)

 (In reply to comment #0)

  Making it:

  

  std::move(a).p();

  

  Does not help.

 

 It does for me...



Note that I only tested 4.9, it could be something missing in the backport.


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread thiago at kde dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #6 from Thiago Macieira thiago at kde dot org 2013-04-25 06:51:33 
UTC ---

void f(A a)

{

std::move(a).p();

}



_Z1fO1A:

.cfi_startproc

jmp _ZNR1A1pEv@PLT  #

.cfi_endproc



Then this looks like a bug in 4.8.1.



But then are we in agreement that a.p() in that function above should call the

lvalue-ref overload? It does make the feature sligthly less useful for me. It

would require writing:



return std::move(std::move(std::move(std::move(QString(%1 %2 %3 %4)

   .arg(42))

  .arg(47))

   .arg(-42))

 .arg(-47));


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread glisse at gcc dot gnu.org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #7 from Marc Glisse glisse at gcc dot gnu.org 2013-04-25 07:08:07 
UTC ---

(In reply to comment #6)

 void f(A a)

 {

 std::move(a).p();

 }

 

 _Z1fO1A:

 .cfi_startproc

 jmp _ZNR1A1pEv@PLT  #

 .cfi_endproc

 

 Then this looks like a bug in 4.8.1.



Indeed, I get s/R/O/ with 4.9.



 But then are we in agreement that a.p() in that function above should call the

 lvalue-ref overload?



Yes.



 It does make the feature sligthly less useful for me. It

 would require writing:

 

 return std::move(std::move(std::move(std::move(QString(%1 %2 %3 %4)

.arg(42))

   .arg(47))

.arg(-42))

  .arg(-47));



Why? You are not naming those return values, so they are still rvalues and will

use the  overload. (not sure why Qstring doesn't provide a mutating interface

for arg)


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread thiago at kde dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #8 from Thiago Macieira thiago at kde dot org 2013-04-25 07:13:44 
UTC ---

Hmm... this might be an effect of the same bug. Can you try this on 4.9?



struct A {

A p() const ;

A p() ;

};



void f()

{

A().p().p();

}



I get:

leaq15(%rsp), %rdi  #, tmp60

call_ZNO1A1pEv@PLT  #

movq%rax, %rdi  # D.69575,

call_ZNKR1A1pEv@PLT #



Is this second call supposed to be to R? If it's to O, it's exactly what I need

to make the feature useful.


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread glisse at gcc dot gnu.org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #9 from Marc Glisse glisse at gcc dot gnu.org 2013-04-25 07:28:01 
UTC ---

(In reply to comment #8)

 Is this second call supposed to be to R? If it's to O, it's exactly what I 
 need

 to make the feature useful.



It is O.


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread thiago at kde dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #10 from Thiago Macieira thiago at kde dot org 2013-04-25 
07:34:21 UTC ---

Great! That changes everything. Now I can provide a mutating arg() overload.



I'll just need some #ifdef and build magic to add the R, O overloads without

removing the nil overloads that already exist (binary compatibility). It

would have been nicer if the lvalue ref overload didn't get extra decoration.


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread jason at gcc dot gnu.org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



Jason Merrill jason at gcc dot gnu.org changed:



   What|Removed |Added



 Status|UNCONFIRMED |ASSIGNED

   Last reconfirmed||2013-04-25

 AssignedTo|unassigned at gcc dot   |jason at gcc dot gnu.org

   |gnu.org |

   Target Milestone|--- |4.8.1

 Ever Confirmed|0   |1



--- Comment #11 from Jason Merrill jason at gcc dot gnu.org 2013-04-25 
14:42:43 UTC ---

Yep, this is a bug in 4.8.1 that was fixed in 4.9 by my follow-on change



* call.c (add_function_candidate): Take the address of 'this' here.

(build_over_call): And here.

(build_new_method_call_1, build_op_call_1): Not here.

(build_user_type_conversion_1): Or here.

(add_candidates): Adjust.



that I thought was too risky for the branch.  I'll fix this differently on the

branch.


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread jason at gcc dot gnu.org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



Jason Merrill jason at gcc dot gnu.org changed:



   What|Removed |Added



 Status|ASSIGNED|RESOLVED

 Resolution||FIXED



--- Comment #12 from Jason Merrill jason at gcc dot gnu.org 2013-04-25 
17:50:25 UTC ---

Fixed.


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-25 Thread glisse at gcc dot gnu.org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #13 from Marc Glisse glisse at gcc dot gnu.org 2013-04-26 
05:05:48 UTC ---

Note for Thiago: please be aware of the risks of returning an rvalue reference,

as opposed to just a value. The following codes will fail at runtime:



Qstring const a=QString(%1 %2 %3 %4).arg(42).arg(47).arg(-42).arg(-47);

Qstring  b=QString(%1 %2 %3 %4).arg(42).arg(47).arg(-42).arg(-47);

for(char c : QString(%1 %2 %3 %4).arg(42).arg(47).arg(-42).arg(-47))...


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-24 Thread thiago at kde dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #1 from Thiago Macieira thiago at kde dot org 2013-04-25 00:45:00 
UTC ---

Here's why I'm asking:



QString has members like:



QString arg(int, [other parameters]) const;



Which are used like so:



return QString(%1 %2 %3 %4).arg(42).arg(47).arg(-42).arg(-47);

// returns 42 47 -42 -47



Right now, each call creates a new temporary, which is required to do memory

allocation. I'd like to avoid the new temporaries by simply reusing the

existing ones:



QString arg(int, [...]) const ; // returns a new copy

QString arg(int, [...]) ; // modifies this object, return *this;



When these two overloads are present, every other call will be to rvalue-ref

and the others to lvalue-ref. That is, the first call (right after the

constructor) calls arg(), which returns an rvalue-ref. The next call will be

to arg(), which returns a temporary, making the third call to arg() again.



I can get the desired behaviour by using the overloads:



QString arg(int, [...]) const ; // returns a new copy

QString arg(int, [...]) ; // returns a moved temporary via return

std::move(*this);



However, the side-effect of that is that we still have 4 temporaries too many,

albeit empty (moved-out) ones. You can see this by counting the number of calls

to the destructor:



$ ~/gcc4.8/bin/g++ -fverbose-asm -fno-exceptions -fPIE -std=c++11 -S -o -

-I$QTOBJDIR/include /tmp/test.cpp | grep -B1 call.*QStringD

movq%rax, %rdi  # tmp82,

call_ZN7QStringD1Ev@PLT #

--

movq%rax, %rdi  # tmp83,

call_ZN7QStringD1Ev@PLT #

--

movq%rax, %rdi  # tmp84,

call_ZN7QStringD1Ev@PLT #

--

movq%rax, %rdi  # tmp85,

call_ZN7QStringD1Ev@PLT #


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-24 Thread thiago at kde dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #2 from Thiago Macieira thiago at kde dot org 2013-04-25 00:45:39 
UTC ---

This was a self-compiled, pristine GCC



gcc version 4.8.1 20130420 (prerelease) (GCC) 

trunk at 198107


[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?

2013-04-24 Thread thiago at kde dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064



--- Comment #3 from Thiago Macieira thiago at kde dot org 2013-04-25 00:53:20 
UTC ---

One more note. Given:



void p(A );

void p(A );



void f(A a)

{

p(a);

}



like the member function case, this calls p(A ). It's slightly surprising at

first glance, but is a known and documented case.



Unlike the member function case, if you do



p(std::move(a));



it will call p(A ).