On Mon, Jul 8, 2013 at 11:59 AM, Sid Sacek
My original idea to return -1 was not very good. Zero is much better.
I'm new to 'shared_ptr< T[] >'; I don't know how long it's been out there and being used in production code, but if all the rules for shared_ptr< T[] > have not yet been set in stone, then maybe there's room for modifications.
My original thought was to make 'size' a requirement for shared_ptr< T[] > since why would anyone use an array without knowing the array's bounds ? Every array has bounds and nobody would touch an array without knowing that information. And placing that information with the array itself makes the most sense to me.
Size could be implied from other components around the pointer. E.g. you could have multiple buffers of the same size encapsulated in a class that maintains this invariant.
If it were made a requirement, then the code might look something like this, or something even more clever:
shared_ptr< char[] > buffer( new char[ 10 ], 10 );
The above constructor would set the capacity value to 10. If however, the coder were to simply do this:
shared_ptr< char[] > buffer( new char[ 10 ] );
It is clear that the coder has no interest in the capacity information for the buffer, and therefore no other part of that programmer's code will be looking for it either. This would be a non-breaking change, since that is the default behavior of shared_ptr
, and the capacity could simply be set to 0.
While that looks feasible, I still would prefer to use a container over a pointer in this case. Providing size manually is error prone at least.
Let me describe how this feature could be used. Imagine your socket library filled user buffers as data arrived. For example:
socket::fill_buffer( shared_ptr
buffer ) { ... } my_socket-> fill_buffer( my_buffer );
In this case, your library doesn't simply want a shared buffer pointer, but it also needs to know where the buffer ends. Of course you could specify that with extra arguments, which is how it has traditionally been done in C, but with buffer objects, the buffer pointer and its size will be kept atomic. That could prevent buffer overflow bugs from occurring.
With manual size provision this is still asking for trouble, IMHO. Just use a plain vector and forget about buffer overruns or insufficient buffer sizes. In fact, you don't share anything here, so by using vector you express your intent more clearly. You may argue about copying the buffer contents or asynchronous operation execution, but move semantics helps here.
The buffer object no longer behaves like a regular shared_ptr<>, but behaves very much like an array, and for all intents and purposes, it is an array, it is a buffer! What I mean is, it is not a pointer anymore, and you can no longer do this:
buffer-> ???? // what can the pointer operator be used for ????
The operator-> would work like with any raw pointer - it would return a pointer to the first element of the array. Specializing the interface based on the template argument is not intuitive, IMHO.