Re: A subtle access issue (may be advanced :-) )
* ld:
On 30 ao?t, 04:42, "Alf P. Steinbach" <al...@start.no> wrote:
* ld:
On 29 ao?t, 09:11, "Alf P. Steinbach" <al...@start.no> wrote:
The following code compiles as-is with g++ and Comeau Online, but not when then
the commented lines are uncommented:
<code>
#include <stddef.h>
template< class T > T* create();
class Base
{
template< class T > friend T* create();
private:
static void* operator new( size_t size )
{
return ::operator new( size );
}
// static void operator delete( void* p )
// {
// ::operator delete( p );
// }
protected:
virtual ~Base() {}
};
class Derived
: public Base
{
public:
Derived() {}
virtual ~Derived() {}
};
template< class T >
T* create() { return new T; }
int main()
{
create<Derived>();}
</code>
With uncommenting the commented code both compilers complain that the Derived
destructor can't access Base::operator delete.
They don't complain that the Derived constructor can't access Base::operator new.
I can understand the lack of complaint for the constructor: the constructor
doesn't need to access the allocation function, which is invoked by the new
expression which is in the context of the create function which has access.
I don't understand the complaint for the destructor. The new expression has to
potentially deallocate, if an expression is thrown. But it manages well to use
the allocation function, so why can't it also use the deallocation function?
In short, why this different treatment?
It almost seems as if the standard supports an implementation technique where
the call to the deallocation function is made directly from *within* the most
derived class' destructor?
[snip explanation of machine code level -- I don't think it should influence
access!]
BTW, why don't you declare Base::operator delete as protected instead
of private since its role is more or less the same as the destructor
~Base() ?
That's what I had to do, but the reason for the "private:" is to express in the
language that a derived class' code can't do 'delete this'.
With protected access it can. :-(
Cheers,
ld.
Thanks :-) Although I disagree (very strongly) that access rules should be
affected by possible implementation techniques for the compiler.
I fully agree that it should not influence the access. I was just
giving a possible explanation why this pre-standard behavior may
happened. In particular it does not follow ISO/IEC 14882:1998(E) (Free
Store) 12.5 ?8
"Access to the deallocation function is checked statically. Hence,
even though a different one might actually be executed, the statically
visible deallocation function is required to be accessible." [example
follow].
Therefore, the compiler should clearly report a diagnostic, whatever
implementation it uses.
Cheers,
ld.
Thanks, but in the given code the new expression does have static access, since
it's in a friend function. It's just the dynamically chosen destructor that
doesn't have access. And I think that rule of the standard is not as it should
be, possibly not even reflecting original intent.
But another thanks: I just posted a response else-thread where I pointed out
what I thought was a double defect in the standard.
Your observation (I didn't see that /8, which *retroactively* modifies the
meaning of /4!) means that I was wrong about one of them, the A in that article,
but I maintain the B of that article -- it's just very wrong to have static
access restricted by a possible dynamic choice, it's not that way anywhere else.
Cheers,
- Alf