public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/61892] New: RVO not occurs with constructor with universal reference arguments
@ 2014-07-24  5:25 tower120 at gmail dot com
  2014-07-24  9:14 ` [Bug c++/61892] " redi at gcc dot gnu.org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: tower120 at gmail dot com @ 2014-07-24  5:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61892

            Bug ID: 61892
           Summary: RVO not occurs with constructor with universal
                    reference arguments
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tower120 at gmail dot com

I'm not sure that this is bug. But this is strange behavior, if you ask me.

LIVE: http://coliru.stacked-crooked.com/a/d11d50f611ed0cee

In the following code:

#include <iostream>

template<class ...ArgsIn>
struct C {

  template<class ...Args>
  C(Args&& ... args) {std::cout << "Ctr\n";}        // elision occurs without
&&

  ~C(){std::cout << "Dstr\n";}
  //C(C&&) { std::cout << "A move was made.\n"; }   // with this and universal
references in ctr, rvo occurs
};

template<class ...Args> 
auto f(Args ... args) {
  int i = 1;
  std::cout << "call "<<std::endl;
  return C<>(i, i, i);
}

int main() {
  std::cout << "Hello World!\n";
  auto obj = f();
}

OUTPUT:

g++ -std=c++1y  -O3 -Winline -Wextra -pthread -pedantic-errors main.cpp -lm  &&
./a.out
Hello World!
call 
Ctr
Ctr
Dstr
Ctr
Dstr
Dstr

=========================================================

1) If I have constructor with "universal" references I need to have ANY move
constructor, so rvo happened. 
2) Moreover, when rvo not happens, it construct object with a wrong number of
arguments:
http://coliru.stacked-crooked.com/a/e3ce8882c68dbef2

=========================================================


P.S.
http://stackoverflow.com/questions/24925137/c-universal-reference-in-constructor-and-return-value-optimization-rvo/24925451#comment38729738_24925137
someone claims that with gcc 4.8.3 this problem not exists. I don't have that
compiler at hand, so I can't check that.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/61892] RVO not occurs with constructor with universal reference arguments
  2014-07-24  5:25 [Bug c++/61892] New: RVO not occurs with constructor with universal reference arguments tower120 at gmail dot com
@ 2014-07-24  9:14 ` redi at gcc dot gnu.org
  2014-07-24  9:57 ` tower120 at gmail dot com
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: redi at gcc dot gnu.org @ 2014-07-24  9:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61892

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to tower120 from comment #0)
> I'm not sure that this is bug. But this is strange behavior, if you ask me.

GCC's behaviour looks correct to me. If it looks strange to you it's because
you have an unconstrained constructor template, and that is usually not a good
idea.

The return statement in f returns an rvalue, so the compiler selects a
constructor that can be called with a non-const rvalue of type C.

Your class has a user-defined destructor, therefore an implicit move
constructor is not defined.

C(Args...) cannot be instantiated as C<C>(C) to copy or move an object, as that
would lead to infinite recursion, so when you have C(Args...) the
implicitly-defined copy constructor C(const C&) is used for the return value,
and it can be elided.

When you declare C(Args&&...) that can be instantiated as C<C>(C&&) to
construct the return value, but as that is not a copy constructor or move
constructor it cannot be elided.

When you declare a user-defined move constructor that will be used, and can be
elided.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/61892] RVO not occurs with constructor with universal reference arguments
  2014-07-24  5:25 [Bug c++/61892] New: RVO not occurs with constructor with universal reference arguments tower120 at gmail dot com
  2014-07-24  9:14 ` [Bug c++/61892] " redi at gcc dot gnu.org
@ 2014-07-24  9:57 ` tower120 at gmail dot com
  2014-07-24 20:26 ` tower120 at gmail dot com
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: tower120 at gmail dot com @ 2014-07-24  9:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61892

--- Comment #2 from tower120 <tower120 at gmail dot com> ---
Well ok, but what about this?

http://coliru.stacked-crooked.com/a/e3ce8882c68dbef2

Why it copy with wrong number of argument?


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/61892] RVO not occurs with constructor with universal reference arguments
  2014-07-24  5:25 [Bug c++/61892] New: RVO not occurs with constructor with universal reference arguments tower120 at gmail dot com
  2014-07-24  9:14 ` [Bug c++/61892] " redi at gcc dot gnu.org
  2014-07-24  9:57 ` tower120 at gmail dot com
@ 2014-07-24 20:26 ` tower120 at gmail dot com
  2014-07-24 23:01 ` rs2740 at gmail dot com
  2014-07-25  9:04 ` redi at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: tower120 at gmail dot com @ 2014-07-24 20:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61892

--- Comment #3 from tower120 <tower120 at gmail dot com> ---
But wait, we talk about move constructor. But this is a template class.
Template class can not have move constructor at all.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/61892] RVO not occurs with constructor with universal reference arguments
  2014-07-24  5:25 [Bug c++/61892] New: RVO not occurs with constructor with universal reference arguments tower120 at gmail dot com
                   ` (2 preceding siblings ...)
  2014-07-24 20:26 ` tower120 at gmail dot com
@ 2014-07-24 23:01 ` rs2740 at gmail dot com
  2014-07-25  9:04 ` redi at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: rs2740 at gmail dot com @ 2014-07-24 23:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61892

TC <rs2740 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rs2740 at gmail dot com

--- Comment #4 from TC <rs2740 at gmail dot com> ---
There's a difference between constructors of template classes and constructors
that are themselves templates. Template classes can have copy and move
constructors (they'd better or std::vector would be useless), but constructors
that are themselves templates are neither copy constructors nor move
constructors, whether or not they belong to a template class or a non-template
class.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/61892] RVO not occurs with constructor with universal reference arguments
  2014-07-24  5:25 [Bug c++/61892] New: RVO not occurs with constructor with universal reference arguments tower120 at gmail dot com
                   ` (3 preceding siblings ...)
  2014-07-24 23:01 ` rs2740 at gmail dot com
@ 2014-07-25  9:04 ` redi at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: redi at gcc dot gnu.org @ 2014-07-25  9:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61892

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to tower120 from comment #2)
> Well ok, but what about this?
> 
> http://coliru.stacked-crooked.com/a/e3ce8882c68dbef2
> 
> Why it copy with wrong number of argument?

It doesn't.

C<>(1, 1, 1) calls the constructor template with three arguments, obviously.

Initializing the return value calls the constructor template with one argument.

(In reply to tower120 from comment #3)
> But wait, we talk about move constructor. But this is a template class.
> Template class can not have move constructor at all.

That's not true.

There is no bug here.


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-07-25  9:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-24  5:25 [Bug c++/61892] New: RVO not occurs with constructor with universal reference arguments tower120 at gmail dot com
2014-07-24  9:14 ` [Bug c++/61892] " redi at gcc dot gnu.org
2014-07-24  9:57 ` tower120 at gmail dot com
2014-07-24 20:26 ` tower120 at gmail dot com
2014-07-24 23:01 ` rs2740 at gmail dot com
2014-07-25  9:04 ` redi at gcc dot gnu.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).