Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Are implicit casts to void*& illegal?

Reply
Thread Tools

Are implicit casts to void*& illegal?

 
 
Ray Gardener
Guest
Posts: n/a
 
      04-19-2006
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
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      04-19-2006
Ray Gardener wrote:
> 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; }


Actually, you need to drop the "void*" part. And there is no need to
check for its null-ness. 'free' does nothing if you pass a null pointer
to it.

> (Yes, its free() instead of operator delete, but I don't think using
> the newer memory semantics matters in this case.)


They may not, but only if the pointer is obtained from 'malloc' or
'realloc'. If you get the pointer from 'new', you can't 'free' it.

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


OK.

> 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*&.


Make your 'safe_free' a template.

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


Yes, and it should be dropped.

> 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)
> { ... }


That's right! It is perfect.

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


It's not overkill. Declare it 'inline' and forget about it.

V
--
Please remove capital As from my address when replying by mail


 
Reply With Quote
 
 
 
 
Ray Gardener
Guest
Posts: n/a
 
      04-19-2006
Yes, you're right; I forgot that this is an inline function anyway.
Sigh... got so paranoid about template instantation bloat I've let it
get the better of me.

Thanks,
Ray


Victor Bazarov wrote:
> Ray Gardener wrote:
>> 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; }

>
> Actually, you need to drop the "void*" part. And there is no need to
> check for its null-ness. 'free' does nothing if you pass a null pointer
> to it.
>
>> (Yes, its free() instead of operator delete, but I don't think using
>> the newer memory semantics matters in this case.)

>
> They may not, but only if the pointer is obtained from 'malloc' or
> 'realloc'. If you get the pointer from 'new', you can't 'free' it.
>
>> 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).

>
> OK.
>
>> 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*&.

>
> Make your 'safe_free' a template.
>
>> 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.

>
> Yes, and it should be dropped.
>
>> 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)
>> { ... }

>
> That's right! It is perfect.
>
>> 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.

>
> It's not overkill. Declare it 'inline' and forget about it.
>
> V

 
Reply With Quote
 
peter koch
Guest
Posts: n/a
 
      04-19-2006

Ray Gardener wrote:
> Yes, you're right; I forgot that this is an inline function anyway.
> Sigh... got so paranoid about template instantation bloat I've let it
> get the better of me.
>
> Thanks,
> Ray

[snip]

Actually i do not believe there is any reason to worry about template
bloat these days. Improvements in the linker and compiler have come a
far way - to an extent that code from different templates will be
merged if the code is the same. This happens for e.g.
std::vector:ush_back which is the same code for int and unsigned int.
So even if your code was not inline, most probably all instantations
would fold to the same code.

/Peter

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how can i generate warnings for implicit casts that lose bits? robert bristow-johnson C Programming 13 07-11-2007 10:03 PM
how can i generate warnings for implicit casts that lose bits? robert bristow-johnson C Programming 76 07-02-2007 08:03 AM
Warnings for implicit casts to a narrower type Pete C++ 3 08-08-2004 07:13 PM
overloading for specific implicit casts Simon Ford C++ 4 09-23-2003 05:06 PM
unwanted implicit casts Andrew C Programming 5 09-12-2003 02:00 AM



Advertisments