* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
@ 2013-04-25 0:45 ` thiago at kde dot org
2013-04-25 0:45 ` thiago at kde dot org
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-25 0:45 UTC (permalink / raw)
To: gcc-bugs
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
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
2013-04-25 0:45 ` [Bug c++/57064] " thiago at kde dot org
@ 2013-04-25 0:45 ` thiago at kde dot org
2013-04-25 0:53 ` thiago at kde dot org
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-25 0:45 UTC (permalink / raw)
To: gcc-bugs
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 #
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
2013-04-25 0:45 ` [Bug c++/57064] " thiago at kde dot org
2013-04-25 0:45 ` thiago at kde dot org
@ 2013-04-25 0:53 ` thiago at kde dot org
2013-04-25 6:19 ` glisse at gcc dot gnu.org
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-25 0:53 UTC (permalink / raw)
To: gcc-bugs
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 &&).
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (2 preceding siblings ...)
2013-04-25 0:53 ` thiago at kde dot org
@ 2013-04-25 6:19 ` glisse at gcc dot gnu.org
2013-04-25 6:34 ` glisse at gcc dot gnu.org
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: glisse at gcc dot gnu.org @ 2013-04-25 6:19 UTC (permalink / raw)
To: gcc-bugs
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...
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (3 preceding siblings ...)
2013-04-25 6:19 ` glisse at gcc dot gnu.org
@ 2013-04-25 6:34 ` glisse at gcc dot gnu.org
2013-04-25 6:51 ` thiago at kde dot org
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: glisse at gcc dot gnu.org @ 2013-04-25 6:34 UTC (permalink / raw)
To: gcc-bugs
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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (4 preceding siblings ...)
2013-04-25 6:34 ` glisse at gcc dot gnu.org
@ 2013-04-25 6:51 ` thiago at kde dot org
2013-04-25 7:13 ` thiago at kde dot org
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-25 6:51 UTC (permalink / raw)
To: gcc-bugs
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));
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (5 preceding siblings ...)
2013-04-25 6:51 ` thiago at kde dot org
@ 2013-04-25 7:13 ` thiago at kde dot org
2013-04-25 7:28 ` glisse at gcc dot gnu.org
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-25 7:13 UTC (permalink / raw)
To: gcc-bugs
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:
leaq 15(%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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (6 preceding siblings ...)
2013-04-25 7:13 ` thiago at kde dot org
@ 2013-04-25 7:28 ` glisse at gcc dot gnu.org
2013-04-25 7:34 ` thiago at kde dot org
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: glisse at gcc dot gnu.org @ 2013-04-25 7:28 UTC (permalink / raw)
To: gcc-bugs
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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (7 preceding siblings ...)
2013-04-25 7:28 ` glisse at gcc dot gnu.org
@ 2013-04-25 7:34 ` thiago at kde dot org
2013-04-25 14:42 ` jason at gcc dot gnu.org
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-25 7:34 UTC (permalink / raw)
To: gcc-bugs
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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (8 preceding siblings ...)
2013-04-25 7:34 ` thiago at kde dot org
@ 2013-04-25 14:42 ` jason at gcc dot gnu.org
2013-04-25 17:50 ` jason at gcc dot gnu.org
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: jason at gcc dot gnu.org @ 2013-04-25 14:42 UTC (permalink / raw)
To: gcc-bugs
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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (9 preceding siblings ...)
2013-04-25 14:42 ` jason at gcc dot gnu.org
@ 2013-04-25 17:50 ` jason at gcc dot gnu.org
2013-04-26 5:05 ` glisse at gcc dot gnu.org
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: jason at gcc dot gnu.org @ 2013-04-25 17:50 UTC (permalink / raw)
To: gcc-bugs
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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (10 preceding siblings ...)
2013-04-25 17:50 ` jason at gcc dot gnu.org
@ 2013-04-26 5:05 ` glisse at gcc dot gnu.org
2013-04-26 6:16 ` thiago at kde dot org
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: glisse at gcc dot gnu.org @ 2013-04-26 5:05 UTC (permalink / raw)
To: gcc-bugs
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))...
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (11 preceding siblings ...)
2013-04-26 5:05 ` glisse at gcc dot gnu.org
@ 2013-04-26 6:16 ` thiago at kde dot org
2013-04-26 8:12 ` redi at gcc dot gnu.org
2013-04-26 13:45 ` thiago at kde dot org
14 siblings, 0 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-26 6:16 UTC (permalink / raw)
To: gcc-bugs
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);
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (12 preceding siblings ...)
2013-04-26 6:16 ` thiago at kde dot org
@ 2013-04-26 8:12 ` redi at gcc dot gnu.org
2013-04-26 13:45 ` thiago at kde dot org
14 siblings, 0 replies; 16+ messages in thread
From: redi at gcc dot gnu.org @ 2013-04-26 8:12 UTC (permalink / raw)
To: gcc-bugs
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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
2013-04-25 0:29 [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called? thiago at kde dot org
` (13 preceding siblings ...)
2013-04-26 8:12 ` redi at gcc dot gnu.org
@ 2013-04-26 13:45 ` thiago at kde dot org
14 siblings, 0 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-26 13:45 UTC (permalink / raw)
To: gcc-bugs
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.
^ permalink raw reply [flat|nested] 16+ messages in thread