std::make_shared<>(), has access to protected constructor

std::make_shared<>(), has access to protected constructor

Hello, I'm using Intel's 12.1 compiler with Visual Studio 2010 IDE, making 64 bit target. See code in 2 attached files.

The problem is that this code compiles and it should trigger an error. As expected, it fails with the Microsoft compiler with error C2248 cannot access protected member... .

The Worker class constructor is not public and so it should not be accessible from std::make_shared<Worker>(...). Is this a compiler defect?

I have tried things such as making the Worker constructor private with the same outcome.
I tried completely removing the Worker constructor with 2 arguments, and the code still compiles with no complaint.
I tried making the call to std::make_shared in the constructor body rather than in member initialization. No improvement.
It seems like the compiler is not checking for access to construct the object managed by the std::shared_ptr<...>.

Thanks for looking

附件尺寸
下载 access.cpp417 字节
下载 access.h558 字节
8 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项

Thanks for the test case!

Georg Zitzlsberger (Intel)的头像

Hello,

I can reproduce the problem you described. In my opinion this should not be the case -- any compiler has to error here. Hence I've filed a defect ticket (DPD200239413) and let you know about the status.

Thank you for the great reproducer!

Best regards,

Georg Zitzlsberger

Hi everybody,

>>...The Worker class constructor is not public and so it should not be accessible from std::make_shared(...). Is this a compiler defect?

Yes. Even if a member mpWorker is declared without the std::shared_ptr template class ( not as a smart pointer ):
...
Worker * operator ->() const;

protected:
// std::shared_ptr< Worker > mpWorker;
Worker *mpWorker;
};
...
any C++compiler should fail with some error, like:

...'Worker::Worker' : cannot access protected member declared in class 'Worker'...

Best regards,
Sergey

Here is a test-case that you could consider as a workaround ( passed with 5 different C/C++ compilers ):
...
class Worker
{
public:
Worker();
virtual ~Worker();

protected:
Worker( string const &vClientName, string const &vUserName );

public:
void SetNames( string const &vClientName, string const &vUserName )
{
mClientName = vClientName;
mUserName = vUserName;
};

protected:
string mClientName;
string mUserName;
};

class Handle
{
public:
Handle( string const &vClientName = "unknown", string const &vUserName = "unknown" );
Handle( Handle const &vRhs );
virtual ~Handle();

public:
Worker * operator ->() const;

protected:
// std::shared_ptr< Worker > mpWorker;
Worker mpWorker;
};

Worker::Worker()
{
}

Worker::Worker( string const &vClientName, string const &vUserName )
{
mClientName = vClientName;
mUserName = vUserName;
}

Worker::~Worker()
{
}

/*
Handle::Handle( string const &vClientName, string const &vUserName ) :
// mpWorker( std::make_shared< Worker >( vClientName, vUserName ) )
// mpWorker( Worker( vClientName, vUserName ) )
{
}
*/

Handle::Handle( string const &vClientName, string const &vUserName )
{
// Case 1 - Compiling error
// (*this).operator->()->mClientName = vClientName; // Cannot be used directly when the member is declared as protected in class 'Worker'
// (*this).operator->()->mUserName = vUserName;

// Case 2 - Compiling error
// mpWorker.mClientName = vClientName; // Cannot be used directly when the member is declared as protected in class 'Worker'
// mpWorker.mUserName = vUserName;

// Case 3 - Success
mpWorker.SetNames( vClientName, vUserName ); // Public 'SetNames(...)' method used instead to initialize members of class 'Worker'
}

Handle::~Handle()
{
}

Worker * Handle::operator ->() const
{
return ( Worker * )&mpWorker;
}

...
void main( void )
{
Handle objAccount( "MyClient", "MyUser" );
}

Thanks for the suggestion. I have implemented a pass-key pattern that works around the access issue from std library, since I don't know the scope of the compiler issue.

>>... I don't know the scope of the compiler issue...

I personally would use a workaround ( Is that a big problem? No. ) because it will take some time to fix the problem with the compiler. At least you should be able to proceed with what you need to do etc.

Georg Zitzlsberger (Intel)的头像

Hello,

this problem will be fixed in Intel(R) Composer XE 2013 Update 2 that's scheduled soon.

Best regards,

Georg Zitzlsberger

登陆并发表评论。