 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Дмитрий Лицкалов Guest
|
Posted: Fri Dec 16, 2005 3:46 pm Post subject: Defect Report: friend operator new/delete namespace scope pr |
|
|
[ Note: forwarded to C++ committee. -sdc ]
Let consider next valid code example:
class C
{
public: enum E {};
friend void* operator new(size_t, E);
friend void operator delete(void*, E);
};
void foo()
{
C::E e;
C* ptr = new(e) C();
}
After moving class C to any namespace this code became ill-formed
and seems no way to make it valid:
namespace N
{
class C
{
public: enum E {};
friend void* operator new(size_t, E);
friend void operator delete(void*, E);
};
}
void foo()
{
N::C::E e;
N::C* ptr = new(e) N::C();
}
CAUSE:
Conflict between two clauses in standard
(ISO/IEC IS 14882:2003, Programming Languages -- C++).
From one side as described in
3.7.3.1 Allocation functions [basic.stc.dynamic.allocation]
"1 An allocation function shall be a class member function or a global
function;
a program is ill-formed if an allocation function is declared in a
namespace
scope other than global scope or declared static in global scope..."
and in 3.7.3.2 Deallocation functions [basic.stc.dynamic.deallocation]
"1 Deallocation functions shall be class member functions or global
functions; a program is ill-formed if deallocation
functions are declared in a namespace scope other than global scope or
declared static in global
scope."
'operator new' and 'operator delete' must be declared in a global scope.
But, from other side, we can't declare they as friend of any class in
a namespace scope other than global scope, because:
7.3.1.2 Namespace member definitions [namespace.memdef]
"3 ... If a friend declaration in a non-local class first declares
a class or function the friend class or function is a member of the
innermost
enclosing namespace. ... When looking for a prior declaration of a class
or a function declared as a friend, and when the name of the friend class or
function is neither a qualified name nor a template-id, scopes outside the
innermost enclosing namespace
scope are not considered."
So, for solve this problem we need to put forward declaration of friend
'operator new' and 'operator delete' to global scope and refer to it in
friend
declaration:
namespace N
{
class C
{
public: enum E {};
friend void* ::operator new(size_t, E);
friend void ::operator delete(void*, E);
};
}
But we can't make forward declaration for this operators because they uses
the type internally declared in class C. Vicious circle.
Some compilers, such as MS VC 6.0 - MS VC 2003, allows workaround:
namespace N
{
class C
{
public: enum E {};
friend void* operator new(size_t, E);
friend void operator delete(void*, E);
};
}
inline
void* operator new(size_t sz, N::C::E e)
{
return N::operator new(sz, e);
}
void foo()
{
N::C::E e;
N::C* ptr = new(e) N::C();
}
but this behavior is not standard compliant.
RESOLUTION:
The best way, IMHO, introduce a new syntax addendum for friend declaration
that allow explicitly inject name of friend function to any desired
namespace scope.
Or, to fix only the described problem, change the text of paragraph 3 of
clause 7.3.1.2 and add an exception to the rule for friend
allocation/deallocaton function.
A scope for such functions must correspond with clauses 3.7.3.1/3.7.3.2.
Dmitriy Litskalov
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|