Anyone know the reason behind this error (C++)?

Started by
9 comments, last by chollida1 17 years, 5 months ago
The following code does not compile in CodeWarrior. The error is "illegal access from 'Foo' to protected/private member 'Foo::Foo( const Foo &)'". Does any C++ guru know why the copy constructor must be public?

class Foo
{
public:
	Foo( int x ) : y( x ) {}
	int y;
private:
	Foo( Foo const & source );
};
 
int bar( Foo const & f )
{
	return f.y;
} 
 
int main( int argc, char * argv[] )
{
	return bar( Foo(0) );    // error here
}



John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Advertisement
[EDIT: misread your code. That is bizarre. No idea why the copy constructor is getting invoked]

-me
Yeah, I've been caught by that one, too. The copy constructor has to be be accessible and in scope for the temp object to be used, even through a const reference. Note that the copy constructor never gets called, but it has to be present and resolvable at link time.

And yes, there is some strong philosophical reason for it, no matter how amazinly obtuse it might seem. I just can't remember what the reason is, since I have no room left in my head for obtuse reasoning.

Stephen M. Webb
Professional Free Software Developer

Strange.

If you compile the code with a public copy constructor, it works but the copy contrustor isnt called, it doesnt need to even be defined for it to compile and link! I believe the compiler needs to be able to legally call the copy contructor, even if the compiler chooses not to.

I think its similar to:

Foo f = Foo(0);

In that the copy constructor doesnt have to be called, but it can be.
I reproduced the behaviour on g++, but the copy constructor is not called. My intuition is that this is done to ensure the transparency of constant reference calling (since it should appear from the call site as if you're calling by value), although I'm not quite convinced.

I'll try to find something about this in the standard.
Interesting question. VS8 compiles this no problem, but then ms arn't renowned for sticking to the standard.
Quote:Original post by Anonymous Poster
Interesting question. VS8 compiles this no problem, but then ms arn't renowned for sticking to the standard.


Did you disable language extensions before trying?
Quote:Original post by ToohrVyk
Quote:Original post by Anonymous Poster
Interesting question. VS8 compiles this no problem, but then ms arn't renowned for sticking to the standard.


Did you disable language extensions before trying?

Oops.
error C2248: 'Foo::Foo' : cannot access private member declared in class 'Foo'


12.1
Quote:
4 A constructor shall not be virtual (10.3) or static (9.4). A constructor can be invoked for a const, volatile or
const volatile object. A constructor shall not be declared const, volatile, or const volatile (9.3.2). const
and volatile semantics (7.1.5.1) are not applied on an object under construction. They come into effect when the
constructor for the most derived object (1.8) ends.


I think the bold may be the reason?
Bold didn't work as AP "A constructor can be invoked for a const.."

heres the full error VS gives
Quote:c:\temp\test.cpp(19) : error C2248: 'Foo::Foo' : cannot access private member declared in class 'Foo'
c:\temp\test.cpp(8) : see declaration of 'Foo::Foo'
c:\temp\test.cpp(3) : see declaration of 'Foo'
while checking that elided copy-constructor 'Foo::Foo(const Foo &)' is callable
c:\temp\test\test\test.cpp(8) : see declaration of 'Foo::Foo'
when converting from 'Foo' to 'const Foo &'

This topic is closed to new replies.

Advertisement