- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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(...). 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
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the test case!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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" );
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>... 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
this problem will be fixed in Intel(R) Composer XE 2013 Update 2 that's scheduled soon.
Best regards,
Georg Zitzlsberger

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page