R
Ray Gardener
I searched around but couldn't find any previous discussion on this, so...
I have a macro that implements a common memory disposal function, e.g.:
#define safe_free(void* pv) if(pv) { ::free(pv); (pv) = NULL; }
(Yes, its free() instead of operator delete, but I don't think using the
newer memory semantics matters in this case.)
Since another project might have an entity of the same name, and macros
are in the global namespace, to avoid namespace collision I thought an
inline function might be better:
namespace myspace
{
inline void safe_free(void*& pv) { ... }
}
(Having pv as a void*& lets pv be assigned to NULL).
However, calling code can no longer do this:
using namespace myspace;
char* p = (char*)::malloc(100);
safe_free(p); // error: char* cannot be
// converted to void*&.
Doing
safe_free((void*)p);
fails also (can't convert void* to void*&), which seems odd because
void* pv = (void*)p;
safe_free(pv);
works fine.
So to use the function, I wound up doing
safe_free((void*&)p);
which is not the end of the world but tragically inelegant considering
that references usually increase elegance. Implicit casts to void* are
legal, but not void*& -- strange.
This is happening in MSVC 6. I was wondering if others had the same
problem in other compilers or other versions of MSVC.
This template would work:
template <type T> void safe_free(T*& p)
{ ... }
but it seems like overkill to have to instantiate a template function
for all possible pointer types when the function only needs the
pointer's value, not the type of object being pointed to.
Ray
I have a macro that implements a common memory disposal function, e.g.:
#define safe_free(void* pv) if(pv) { ::free(pv); (pv) = NULL; }
(Yes, its free() instead of operator delete, but I don't think using the
newer memory semantics matters in this case.)
Since another project might have an entity of the same name, and macros
are in the global namespace, to avoid namespace collision I thought an
inline function might be better:
namespace myspace
{
inline void safe_free(void*& pv) { ... }
}
(Having pv as a void*& lets pv be assigned to NULL).
However, calling code can no longer do this:
using namespace myspace;
char* p = (char*)::malloc(100);
safe_free(p); // error: char* cannot be
// converted to void*&.
Doing
safe_free((void*)p);
fails also (can't convert void* to void*&), which seems odd because
void* pv = (void*)p;
safe_free(pv);
works fine.
So to use the function, I wound up doing
safe_free((void*&)p);
which is not the end of the world but tragically inelegant considering
that references usually increase elegance. Implicit casts to void* are
legal, but not void*& -- strange.
This is happening in MSVC 6. I was wondering if others had the same
problem in other compilers or other versions of MSVC.
This template would work:
template <type T> void safe_free(T*& p)
{ ... }
but it seems like overkill to have to instantiate a template function
for all possible pointer types when the function only needs the
pointer's value, not the type of object being pointed to.
Ray