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

AdjuntoTamaño
Descargar access.cpp417 bytes
Descargar access.h558 bytes
publicaciones de 8 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.

Thanks for the test case!

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.

Hello,

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

Best regards,

Georg Zitzlsberger

Deje un comentario

Por favor inicie sesión para agregar un comentario. ¿No es socio? Únase ya