public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/57064] New: [clarification requested] Which overload with ref-qualifier should be called?
@ 2013-04-25 0:29 thiago at kde dot org
2013-04-25 0:45 ` [Bug c++/57064] " thiago at kde dot org
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: thiago at kde dot org @ 2013-04-25 0:29 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064
Bug #: 57064
Summary: [clarification requested] Which overload with
ref-qualifier should be called?
Classification: Unclassified
Product: gcc
Version: 4.8.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: thiago@kde.org
I'm not sure this is a bug. I am requesting clarification on the behaviour.
>From the C++11 standard (13.3.3.2 [over.ics.rank] p 3):
struct A {
void p() &;
void p() &&;
};
void f()
{
A a;
a.p();
A().p();
}
GCC 4.8.1 correctly calls the lvalue-ref overload first, then the rvalue
overload second.
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. Making it:
std::move(a).p();
Does not help.
^ 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 ` 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 #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
` (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 #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
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
end of thread, other threads:[~2013-04-26 13:45 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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
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
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
2013-04-26 8:12 ` redi at gcc dot gnu.org
2013-04-26 13:45 ` thiago at kde dot org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).