Boost logo

Boost :

From: Mike Tegtmeyer (tegtmeye_at_[hidden])
Date: 2007-11-02 19:00:12


Good answer

The common retort from new folks that I hear to the "no attempt to
interpret the pointer value" argument is more of a pragmatic one: it
doesn't behave as expected in the fundamental case. I appreciate the other
side of the coin awkward trick example however, and as I sit and think
about it - that is much more painful.

The counter argument that I hear from not-new folks however is that it
takes some work to not leak the resource during an exception in the
shared_ptr construction. Therefore, the ugliness to maintain integrity
diminishes it's usefulness. ie

FILE *in = fopen(...);
if(!in)
  return/throw badness;

//may throw here, 'in' is lost
shared_ptr<FILE> fin(in,fclose);

Therefore,

<third_person>

struct file_sentry {
         file_sentry(FILE *_f) :f(_f) {}
         ~file_sentry() { if(f) fclose(f); }
         FILE *f;
};

file_sentry sentry(fopen(...));
if(!sentry.f)
         return/throw badness;

//if throw here, 'in' gets closed
shared_ptr<FILE> fin(sentry.f,fclose);
sentry.f = 0;

But gee, that was a lot of work, maybe if I just refactor file_sentry to
resource_sentry so it does what I want...

- or -

shared_ptr<file_sentry> ... do I really have to call new here???

- will maybe if I point shared_pointer to a local object, eh my head
hurts, never mind, exception safety is just mental gymnastics anyway...

</third_person>

I can understand the frustration.

Mike

On Sat, 3 Nov 2007, Peter Dimov wrote:

> Mike Tegtmeyer:
>
>> I am often asked why shared_ptr always uses the custom deleter even when
>> the pointer argument is zero. I know it is safe to delete a NULL pointer
>> so this works with delete but it would seem that if the user is giving a
>> custom deleter, then they are probably doing something else. ie
>>
>> //will crash if fread returns 0
>> shared_ptr<FILE> foo(fread("foo.txt","r"),fclose);
>
> This is a good question without an easy answer. There is a conflict between
> semantical purity (shared_ptr does not attempt to interpret the pointer
> value in any way, this task is left to the deleter and ultimately to the
> programmer) and expressive power (the user may, in fact, want his deleter to
> be called even for NULL) on one side, and convenience for use cases like
> fopen, on the other.
>
> Neither alternative is a clear winner. What tips the scales somewhat is that
> (a) typically an idiomatic C++ wrapper over FILE would not construct a
> shared_ptr when fopen fails, it will throw an exception, (b) many resource
> releasing functions (such as 'free') do ignore NULLs instead of crashing,
> and (c) there is a relatively easy (if inconvenient) workaround.
>
> (If shared_ptr didn't call the deleter for NULLs, one would have to use
> somewhat awkward tricks such as encode NULL as (void*)-1 in the reverse
> case.)
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk