Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > copy ctor being private and compilation error

Reply
Thread Tools

copy ctor being private and compilation error

 
 
subramanian100in@yahoo.com, India
Guest
Posts: n/a
 
      08-03-2010
Consider the following program x.cpp:

#include <cstdlib>
#include <iostream>

using namespace std;

class Test
{
public:
explicit Test(int arg = 10);
ostream& writeTo(ostream& os) const;
private:
Test(const Test& rhs);
int val;
};

inline Test::Test(int arg) : val(arg)
{
cout << "Test one-argument-ctor called" << endl;
}

inline ostream& Test::writeTo(ostream& os) const
{
return os << val;
}

inline ostream& operator<<(ostream& os, const Test& obj)
{
return obj.writeTo(os);
}

int main()
{
const Test& ref = Test();
cout << ref << endl;

return EXIT_SUCCESS;
}

When I compile this program as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

I get the following compilation error:
x.cpp: In function `int main()':
x.cpp:12: error: `Test::Test(const Test&)' is private
x.cpp:33: error: within this context

Though the copy ctor of Test is private, the statement
const Test& ref = Test();
involves only taking a 'const reference' to the temporary Test object
created by Test() on the RHS. Since only a reference is made, why does
this statement require the copy ctor ?
Kindly clarify, if necessary with a program example.

Thanks
V.Subramanian
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      08-03-2010
On 08/ 3/10 04:12 PM, http://www.velocityreviews.com/forums/(E-Mail Removed), India wrote:
> Consider the following program x.cpp:
>

<snip>
>
> int main()
> {
> const Test& ref = Test();
> cout<< ref<< endl;
>
> return EXIT_SUCCESS;
> }
>
> When I compile this program as
> g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
>
> I get the following compilation error:
> x.cpp: In function `int main()':
> x.cpp:12: error: `Test::Test(const Test&)' is private
> x.cpp:33: error: within this context
>
> Though the copy ctor of Test is private, the statement
> const Test& ref = Test();
> involves only taking a 'const reference' to the temporary Test object
> created by Test() on the RHS. Since only a reference is made, why does
> this statement require the copy ctor ?


It appears to be a bug in the version (3.4.x?) of gcc you are using.

--
Ian Collins
 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      08-03-2010
Ian Collins wrote:

> On 08/ 3/10 04:12 PM, (E-Mail Removed), India wrote:
>> Consider the following program x.cpp:
>>

> <snip>


Just to be more explicit, I recall the declaration of Test:

class Test
{
public:
explicit Test(int arg = 10);
ostream& writeTo(ostream& os) const;
private:
Test(const Test& rhs);
int val;
};

Note the private copy constructor.


>> int main()
>> {
>> const Test& ref = Test();
>> cout<< ref<< endl;
>>
>> return EXIT_SUCCESS;
>> }
>>
>> When I compile this program as
>> g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
>>
>> I get the following compilation error:
>> x.cpp: In function `int main()':
>> x.cpp:12: error: `Test::Test(const Test&)' is private
>> x.cpp:33: error: within this context
>>
>> Though the copy ctor of Test is private, the statement
>> const Test& ref = Test();
>> involves only taking a 'const reference' to the temporary Test object
>> created by Test() on the RHS. Since only a reference is made, why does
>> this statement require the copy ctor ?

>
> It appears to be a bug in the version (3.4.x?) of gcc you are using.


It's not a bug. The code is invalid in C++98 and C++03 by [8.5.3/5] which
requires the copy constructor to be visibile. The compiler is free (but not
required) to make a copy of the object before initializing the reference.
The bug is in newer g++ versions (starting with the 4.3 series or
thereabout).

The code will be legal in C++0x.


Best

Kai-Uwe Bux
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      08-03-2010
On 08/ 3/10 06:37 PM, Kai-Uwe Bux wrote:
> Ian Collins wrote:
>
>> On 08/ 3/10 04:12 PM, (E-Mail Removed), India wrote:
>>> Consider the following program x.cpp:
>>>

>> <snip>

>
> Just to be more explicit, I recall the declaration of Test:
>
> class Test
> {
> public:
> explicit Test(int arg = 10);
> ostream& writeTo(ostream& os) const;
> private:
> Test(const Test& rhs);
> int val;
> };
>
> Note the private copy constructor.
>
>
>>> int main()
>>> {
>>> const Test& ref = Test();
>>> cout<< ref<< endl;
>>>
>>> return EXIT_SUCCESS;
>>> }
>>>
>>> When I compile this program as
>>> g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
>>>
>>> I get the following compilation error:
>>> x.cpp: In function `int main()':
>>> x.cpp:12: error: `Test::Test(const Test&)' is private
>>> x.cpp:33: error: within this context
>>>
>>> Though the copy ctor of Test is private, the statement
>>> const Test& ref = Test();
>>> involves only taking a 'const reference' to the temporary Test object
>>> created by Test() on the RHS. Since only a reference is made, why does
>>> this statement require the copy ctor ?

>>
>> It appears to be a bug in the version (3.4.x?) of gcc you are using.

>
> It's not a bug. The code is invalid in C++98 and C++03 by [8.5.3/5] which
> requires the copy constructor to be visibile. The compiler is free (but not
> required) to make a copy of the object before initializing the reference.
> The bug is in newer g++ versions (starting with the 4.3 series or
> thereabout).


Ah, OK. I missed "The constructor that would be used to make the copy
shall be callable whether or not the copy is actually done."

--
Ian Collins
 
Reply With Quote
 
Gennaro Prota
Guest
Posts: n/a
 
      08-03-2010
On 03/08/2010 6.12, (E-Mail Removed), India wrote:
[...]
> int main()
> {
> const Test& ref = Test();
> cout<< ref<< endl;
>
> return EXIT_SUCCESS;
> }
>
> When I compile this program as
> g++ -std=c++98 -pedantic -Wall -Wextra x.cpp
>
> I get the following compilation error:
> x.cpp: In function `int main()':
> x.cpp:12: error: `Test::Test(const Test&)' is private
> x.cpp:33: error: within this context
>
> Though the copy ctor of Test is private, the statement
> const Test& ref = Test();
> involves only taking a 'const reference' to the temporary Test object
> created by Test() on the RHS. Since only a reference is made, why does
> this statement require the copy ctor ?
> Kindly clarify, if necessary with a program example.


I don't know if this is in the FAQ but it should be C++98
required this.

And although it allowed the copy to be omitted it required the
copy constructor to be accessible anyway, so that your code
would not suddenly broke because you switched from a compiler
that omitted the copy to one that didn't.

C++0x has a different rule; see core issue 391:

<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#391>

--
Gennaro Prota | name.surname yahoo.com
Breeze C++ (preview): <https://sourceforge.net/projects/breeze/>
Do you need expertise in C++? I'm available.
 
Reply With Quote
 
subramanian100in@yahoo.com, India
Guest
Posts: n/a
 
      08-10-2010
* Kai-Uwe Bux <(E-Mail Removed)> wrote:
> Ian Collins wrote:
> > On 08/ 3/10 04:12 PM, (E-Mail Removed), India wrote:
> >> Consider the following program x.cpp:

>
> > <snip>

>
> Just to be more explicit, I recall the declaration of Test:
>
> class Test
> {
> public:
> explicit Test(int arg = 10);
> ostream& writeTo(ostream& os) const;
> private:
> Test(const Test& rhs);
> int val;
> };
>
> Note the private copy constructor.
>
>
>
> >> int main()
> >> {
> >> const Test& ref = Test();
> >> cout<< ref<< endl;

>
> >> return EXIT_SUCCESS;
> >> }

>
> >> When I compile this program as
> >> g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

>
> >> I get the following compilation error:
> >> x.cpp: In function `int main()':
> >> x.cpp:12: error: `Test::Test(const Test&)' is private
> >> x.cpp:33: error: within this context

>
> >> Though the copy ctor of Test is private, the statement
> >> const Test& ref = Test();
> >> involves only taking a 'const reference' to the temporary Test object
> >> created by Test() on the RHS. Since only a reference is made, why does
> >> this statement require the copy ctor ?

>
> > It appears to be a bug in the version (3.4.x?) of gcc you are using.

>
> It's not a bug. The code is invalid in C++98 and C++03 by [8.5.3/5] which
> requires the copy constructor to be visibile. The compiler is free (but not
> required) to make a copy of the object before initializing the reference.
> The bug is in newer g++ versions (starting with the 4.3 series or
> thereabout).
>
> The code will be legal in C++0x.
>
> Best
>
> Kai-Uwe Bux


Thanks for your clarification. In the above program suppose I replace
the line
const Test& ref = Test();
with
Test obj;
const Test& ref = obj;
the program compiles fine. Here is the complete modified program:

#include <cstdlib>
#include <iostream>

using namespace std;

class Test
{
public:
explicit Test(int arg = 10);
ostream& writeTo(ostream& os) const;
private:
Test(const Test& rhs);
int val;
};

inline Test::Test(int arg) : val(arg)
{
cout << "Test one-argument-ctor called" << endl;
}

inline ostream& Test::writeTo(ostream& os) const
{
return os << val;
}

inline ostream& operator<<(ostream& os, const Test& obj)
{
return obj.writeTo(os);
}

int main()
{
Test obj;
const Test& ref = obj; // note the change here
cout << ref << endl;

return EXIT_SUCCESS;
}

Suppose I compile this program with g++3.4.3 as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

it compiles fine and produces the output:
Test one-argument-ctor called
10

My question is why doesn't the compiler allow
const Test& ref = Test();
but it allows
Test obj;
const Test& ref = obj; // note the change here
I am unable to understand the difference. Kindly clarify the reason
regarding how this modified program gets compiled while the earlier
version doesn't.

Thanks
V.Subramanian
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      08-10-2010
On 10 Aug., 10:01, subramanian10 wrote:
> * Kai-Uwe Bux wrote:
> > It's not a bug. The code is invalid in C++98 and C++03 by [8.5.3/5] which
> > requires the copy constructor to be visibile. The compiler is free (but not
> > required) to make a copy of the object before initializing the reference.
> > The bug is in newer g++ versions (starting with the 4.3 series or
> > thereabout).

>
> > The code will be legal in C++0x.

>
> Thanks for your clarification. In the above program suppose I replace
> the line
> * * const Test& *ref = Test();
> with
> * * Test obj;
> * * const Test& *ref = obj;
> the program compiles fine.


[snip]

> My question is why doesn't the compiler allow
> const Test& ref = Test();
> but it allows
> Test obj;
> const Test& ref = obj; // note the change here


For some reason C++98 only requires an object to be copyable if you
try to initialize a reference with an *rvalue* expression. In your
case Test() is such an *rvalue* whereas obj is an *lvalue*. Your
example with 'obj' is really valid C++. As it has already been said,
this restriction will go away in C++0x. I suppose, that's because none
of the current compilers actually need to use the copy ctor in both of
these cases.

Cheers!
SG
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
conditions for automatic generation of default ctor, copy ctor,and default assignment operator (operator) puzzlecracker C++ 8 04-15-2008 09:56 PM
copy ctor vs default ctor subramanian100in@yahoo.com, India C++ 2 08-15-2007 10:49 AM
static array initialization and private copy ctor John Salmon C++ 3 12-11-2006 01:38 PM
Templates, copy ctor and type-conversion ctor NVH C++ 8 07-06-2006 07:19 PM
three times copy ctor called, one ctor called, why? Apricot C++ 4 04-16-2004 07:55 AM



Advertisments