Allocation function in a namespace

M

mackenzie

I was wondering why it is "ill-formed if an allocation function is
declared in a namespace"? I have done some searching on the web and
can not find a reason why; I have stumbled across a few other users
asking similar questions but there are no definitive replies that I
could find.

To me a namespace specifies a set of functionality. From an
application point of view a namespace could easily specify a set of
interrelated processes and the objects which those processes operate
upon. In some applications those objects might be easily accessed
(with semaphore protection) using a shared memory segment. In this
case one would not want to overload the global new operator; however,
one may want to overload an operator new function which applies only
to that particular name space. This scoped operator new would
dynamically allocate memory from a shared memory system for the set of
processes and objects described by the namespace.
From the standard:
"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

"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."

Thank you,
Parker Mackenzie
 
D

Davlet Panech

mackenzie said:
I was wondering why it is "ill-formed if an allocation function is
declared in a namespace"? I have done some searching on the web and
can not find a reason why; I have stumbled across a few other users
asking similar questions but there are no definitive replies that I
could find.

I'm sure the the standard authors had their reasons; consider this:

namespace A {
class X{};
}

....
X *px = new X;

using namespace B;
delete px;

If multiple allocation/deallocation functions were allowed which of them
should be called in the above example? Even if there was a way to
qualify new/delete with namespace ids, having them re-routed to
different allocation functions just because of a "using" declaration
would make programmers' lives... "interesting".

D.
 
M

mackenzie

Thanks for the reply.

In my opinion, the using declaration should probably only be used when
porting older code to C++. In all other cases one should use a
definitive reference to the function being called.

So using your example:

namespace A {
class X {
public:
static X* getInstance();
private:
static X* instance_;
};

X* X::instance_ = 0;

X* X::getInstance() {
if( 0 == instance_ )
instance_ = new X;
return( instance_ );
}

void* operator new( size_t size )
{
return( allocateSharedMemory( size ) );
}
}

int myFunc() {
int* someData = new int;
A::X* px = A::X::getInstance();
}

The idea being that all objects that were allocated in the namespace A
would use A::eek:perator new. All other objects would be allocated using
the memory allocation function provided by their own name space.

In this way a namespace could easily represent a group of objects
which not only share a common functionality set; but they could also
implicitly share the same memory allocation methods.

Thanks again,
Parker
 
J

Jerry Coffin

[ commenting on: "using namespace B;" ]
In my opinion, the using declaration should probably only be used when
porting older code to C++. In all other cases one should use a
definitive reference to the function being called.

Just FWIW, that's a using directive, not a using declaration. A using
declaration is something like 'using B::X;'

IMO, there are times that a using directive makes sense. For example,
consider writing a generic sort function. If the implementer of the type
being sorted has provided their own swap, you want to use that, but if
they haven't, you want to use std::swap. You can achieve that with a
using directive:

template <class T>
mysort( /* ... */ ) {

using namespace std;

// ...
if (t2 > t1)
swap(t1, t2);
}

Now, if T's namespace contains a 'swap' function that takes the right
arguments, Koenig lookup will find and use that for our swap above. If
there's not one, std::swap will be found and used instead.

In this case, we want to delay choosing the swap function until our
template is actually instantiated. We can't do that by specifying it
explicitly -- we have to leave the compiler the leeway to choose one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,125
Latest member
VinayKumar Nevatia_
Top