public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* copy ctor not called
@ 2005-07-02 18:21 Jeroen Wijnhout
  2005-07-02 19:17 ` Travis Spencer
  2005-07-03 12:27 ` Dirk Jagdmann
  0 siblings, 2 replies; 9+ messages in thread
From: Jeroen Wijnhout @ 2005-07-02 18:21 UTC (permalink / raw)
  To: gcc-help

Hi,

Consider a class with a copy constructor:

class A
{
public:
  A(int i) : m_i(i) 
  {
    cout << "A(int i)" << endl;
  }

  A(const A &a)
  {
    cout << "A(const A &a)" << endl;
    m_i = a.i();
  }

  int i() { return m_i; }

private:
  int m_i;
};

now if I do something like:
A a = 2;
the output should be:
A(int i)
A(const A &a)
the actual output is:
A(int i)

Now, I understand that gcc optimizes away the copy constructor and interprets
the code as:
A a(2);

However, is there a way to force gcc to use the copy constructor?

best,
Jeroen

P.S.: I'm not on the list.
-- 
Kile -- KDE Integrated LaTeX Environment
http://kile.sourceforge.net

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

* Re: copy ctor not called
  2005-07-02 18:21 copy ctor not called Jeroen Wijnhout
@ 2005-07-02 19:17 ` Travis Spencer
  2005-07-03  8:15   ` Jeroen Wijnhout
  2005-07-03 12:27 ` Dirk Jagdmann
  1 sibling, 1 reply; 9+ messages in thread
From: Travis Spencer @ 2005-07-02 19:17 UTC (permalink / raw)
  To: Jeroen Wijnhout; +Cc: gcc-help

On 7/2/05, Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> wrote:
> Consider a class with a copy constructor:
> 
> class A
> {
> public:
>   A(int i) : m_i(i)
>   {
>     cout << "A(int i)" << endl;
>   }
> 
>   A(const A &a)
>   {
>     cout << "A(const A &a)" << endl;
>     m_i = a.i();

This doesn't compile:

copyctor.cpp: In copy constructor `A::A(const A&)':
copyctor.cpp:16: error: passing `const A' as `this' argument of `int A::i()'
   discards qualifiers

This does though:

    A(const A &a) : m_i(a.m_i)
    {
        cout << "A(const A &a)" << endl;
//        m_i = a.i();
    }

> Now, I understand that gcc optimizes away the copy constructor and interprets
> the code as:
> A a(2);
> 
> However, is there a way to force gcc to use the copy constructor?
> 

If I were a jerk, this is where I would say to RTFM, but since I'm not
I'll kindly point out the -fno-elide-constructors flag:

> CXXFLAGS=-fno-elide-constructors g++ -fno-elide-constructors  copyctor.cpp  -o copyctor
> ./copyctor
A(int i)
A(const A &a)

-- 

Regards,

Travis Spencer
Portland, OR USA

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

* Re: copy ctor not called
  2005-07-02 19:17 ` Travis Spencer
@ 2005-07-03  8:15   ` Jeroen Wijnhout
  0 siblings, 0 replies; 9+ messages in thread
From: Jeroen Wijnhout @ 2005-07-03  8:15 UTC (permalink / raw)
  To: gcc-help

On Saturday 02 July 2005 09:17 pm, Travis Spencer wrote:
> On 7/2/05, Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> wrote:
> > Consider a class with a copy constructor:
> >
> > class A
> > {
> > public:
> >   A(int i) : m_i(i)
> >   {
> >     cout << "A(int i)" << endl;
> >   }
> >
> >   A(const A &a)
> >   {
> >     cout << "A(const A &a)" << endl;
> >     m_i = a.i();
>
> This doesn't compile:
>
> copyctor.cpp: In copy constructor `A::A(const A&)':
> copyctor.cpp:16: error: passing `const A' as `this' argument of `int
> A::i()' discards qualifiers

Sorry about that, should have been:
int i() const
{
  return m_i;
}

> > Now, I understand that gcc optimizes away the copy constructor and
> > interprets the code as:
> > A a(2);
> >
> > However, is there a way to force gcc to use the copy constructor?
>
> If I were a jerk, this is where I would say to RTFM, but since I'm not
> I'll kindly point out the -fno-elide-constructors flag:

Actually I did, missed that, but thanks for pointing it out. ;-)

> > CXXFLAGS=-fno-elide-constructors g++ -fno-elide-constructors 
> > copyctor.cpp  -o copyctor ./copyctor

Indeed this works as it should.

best,
Jeroen
-- 
Kile -- KDE Integrated LaTeX Environment
http://kile.sourceforge.net

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

* Re: copy ctor not called
  2005-07-02 18:21 copy ctor not called Jeroen Wijnhout
  2005-07-02 19:17 ` Travis Spencer
@ 2005-07-03 12:27 ` Dirk Jagdmann
  2005-07-03 13:44   ` Jeroen Wijnhout
  1 sibling, 1 reply; 9+ messages in thread
From: Dirk Jagdmann @ 2005-07-03 12:27 UTC (permalink / raw)
  To: Jeroen Wijnhout; +Cc: gcc-help

The behaviour of gcc is standard compliant, since an assignment in the
same statement as a variable declaration is always treated by the copy
constructor. The mentioned gcc switch
-fno-elide-constructors will work, but on other compilers you'll have
the same behaviour again.

-- 
---> Dirk Jagdmann
----> http://cubic.org/~doj
-----> http://llg.cubic.org

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

* Re: copy ctor not called
  2005-07-03 12:27 ` Dirk Jagdmann
@ 2005-07-03 13:44   ` Jeroen Wijnhout
  2005-07-05 14:10     ` Eljay Love-Jensen
  0 siblings, 1 reply; 9+ messages in thread
From: Jeroen Wijnhout @ 2005-07-03 13:44 UTC (permalink / raw)
  To: gcc-help

On Sunday 03 July 2005 02:26 pm, Dirk Jagdmann wrote:
> The behaviour of gcc is standard compliant, since an assignment in the
> same statement as a variable declaration is always treated by the copy
> constructor. 

This is what I expected, yet the copy constructor wasn't called. The copy 
constructor call was optimized away and -fno-elide-constructors will turn off 
this optimization.

> The mentioned gcc switch 
> -fno-elide-constructors will work, but on other compilers you'll have
> the same behaviour again.

Hmm, I get the feeling that the first part of your message is not as you 
intended. 

The point is that if I make the copy constructor private, 
I get a compile error:
error: `Foo::Foo(const Foo&)' is private
Which suggests that the copy constructor should be called in statements like:

A a = 2;

So, I'm wondering what the standard actually says. If A a =2; always means
A a(2); then I don't see why you would need the copy constructor to be public.

I've found the following in the comp.lang.c++.moderated archive:

"TITLE: direct and copy initialization

UPDATE:  In the last case ("T t3 = u;") the
user-defined conversion and the T copy constructor must
both be called.  In CD2 and until the London meeting in
July 1997, the compiler was permitted to elide the copy
constructor call as long as the copy constructor could
have been called (i.e., was accessible).  Since July
1997 and in the final draft standard, the compiler may
not make this optimization to elide the copy
constructor call."

To me this says, that I -fno-elide-constructors should be the default 
behavior. Which it isn't (at least for gcc 3.3.4).

best,
Jeroen
-- 
Kile -- KDE Integrated LaTeX Environment
http://kile.sourceforge.net

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

* Re: copy ctor not called
  2005-07-03 13:44   ` Jeroen Wijnhout
@ 2005-07-05 14:10     ` Eljay Love-Jensen
  2005-07-07 11:45       ` Jeroen Wijnhout
  2005-07-07 12:02       ` Eljay Love-Jensen
  0 siblings, 2 replies; 9+ messages in thread
From: Eljay Love-Jensen @ 2005-07-05 14:10 UTC (permalink / raw)
  To: Jeroen Wijnhout, gcc-help

Hi Jeroen,

>To me this says, that I -fno-elide-constructors should be the default behavior. Which it isn't (at least for gcc 3.3.4).

Due to the design and evolution of C++, your expectation that "-fno-elide-constructors should be the default behavior" is not the case.

I can understand where a person would expect that to be the situation.

However, C++ standard has the elide "optimization" be the default behavior for proper C++, and the -fno-elide-constructors is a non-compliant pessimization.

Moreso, you've touched up the (surprising?) requirement for the copy constructor to be public.

These C++ anachronisms are due in large part to the design and evolution of C++.  They are legacy warts.

Sincerely,
--Eljay

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

* Re: copy ctor not called
  2005-07-05 14:10     ` Eljay Love-Jensen
@ 2005-07-07 11:45       ` Jeroen Wijnhout
  2005-07-07 12:02       ` Eljay Love-Jensen
  1 sibling, 0 replies; 9+ messages in thread
From: Jeroen Wijnhout @ 2005-07-07 11:45 UTC (permalink / raw)
  To: gcc-help

> Hi Jeroen,
>
>>To me this says, that I -fno-elide-constructors should be the default
>> behavior. Which it isn't (at least for gcc 3.3.4).
>
> Due to the design and evolution of C++, your expectation that
> "-fno-elide-constructors should be the default behavior" is not the case.
>
> I can understand where a person would expect that to be the situation.
>
> However, C++ standard has the elide "optimization" be the default behavior
> for proper C++, and the -fno-elide-constructors is a non-compliant
> pessimization.

Hmm, I have the 2005 edition of "C++ Primer", which I kind of trusted
because one of the authors was involved in the C++ ISO standards
committee. They write
in section 13.1 (page 477):
"Copy-initialization always involves the copy constructor".
According to your statement they are wrong.

> Moreso, you've touched up the (surprising?) requirement for the copy
> constructor to be public.
>
> These C++ anachronisms are due in large part to the design and evolution
> of C++.  They are legacy warts.

Thanks for your explanation.

best,
Jeroen

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

* Re: copy ctor not called
  2005-07-05 14:10     ` Eljay Love-Jensen
  2005-07-07 11:45       ` Jeroen Wijnhout
@ 2005-07-07 12:02       ` Eljay Love-Jensen
  2005-07-08 18:26         ` Jeroen Wijnhout
  1 sibling, 1 reply; 9+ messages in thread
From: Eljay Love-Jensen @ 2005-07-07 12:02 UTC (permalink / raw)
  To: Jeroen Wijnhout, gcc-help

Hi Jeroen,

>According to your statement they are wrong.

Please re-read my statement.  My statement does not contradict what you cited from C++ Primer.

What is being elided is the assignment operator, not the copy constructor.  The copy constructor is still being used for initialization.

Sincerely,
--Eljay

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

* Re: copy ctor not called
  2005-07-07 12:02       ` Eljay Love-Jensen
@ 2005-07-08 18:26         ` Jeroen Wijnhout
  0 siblings, 0 replies; 9+ messages in thread
From: Jeroen Wijnhout @ 2005-07-08 18:26 UTC (permalink / raw)
  To: gcc-help

[-- Attachment #1: Type: text/plain, Size: 951 bytes --]

On Thursday 07 July 2005 02:04 pm, Eljay Love-Jensen wrote:
> Hi Jeroen,
>
> >According to your statement they are wrong.
>
> Please re-read my statement.  My statement does not contradict what you
> cited from C++ Primer.
>
> What is being elided is the assignment operator, not the copy constructor. 
> The copy constructor is still being used for initialization.

Glad to hear that you agree with C++ primer ;-). However, as I found out, the 
default behavior of gcc 3.3.4 is not to call the copy constructor in:
Foo f = 2;
instead it uses direct initialization. I've written a simple test program that 
shows this quite clearly. 

So here the default behavior of gcc contradicts with what I've read in C++ 
primer.

The assigment operator is never called in the statement above, with or without 
-fno-elide-constructors.

See the attached code for an example.

best,
Jeroen
-- 
Kile -- KDE Integrated LaTeX Environment
http://kile.sourceforge.net

[-- Attachment #2: CopyCtor.tar.gz --]
[-- Type: application/x-tgz, Size: 730 bytes --]

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

end of thread, other threads:[~2005-07-08 18:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-02 18:21 copy ctor not called Jeroen Wijnhout
2005-07-02 19:17 ` Travis Spencer
2005-07-03  8:15   ` Jeroen Wijnhout
2005-07-03 12:27 ` Dirk Jagdmann
2005-07-03 13:44   ` Jeroen Wijnhout
2005-07-05 14:10     ` Eljay Love-Jensen
2005-07-07 11:45       ` Jeroen Wijnhout
2005-07-07 12:02       ` Eljay Love-Jensen
2005-07-08 18:26         ` Jeroen Wijnhout

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).