On 07/07/2010, at 5:51 PM, vincent habchi wrote:

> The double indirection is necessary in order for the master data pointer 
> (*data) to progress through the data chunk; since that chunk can hold 
> different items, I have to decode it on the fly and call the appropriate 
> method that interprets an appropriate block of data. If I were using a 
> '(double *)data' instead, I would end up incrementing a local copy, and the 
> main pointer in the caller method would not be altered. Or am I mistaken?

OK, so the idea is to leave the pointer you're given incremented past the chunk 
of data it parsed.

I guess it's question of style. To me this seems like one part of the code (the 
caller) is praying and hoping that another part it calls does the right thing 
as a side-effect of its true function, instead of just telling it what to do. 
If you know in advance how many items to process, there's no reason to do it 
that way.

I think what I'd do is tell the called function how many items to process. Then 
whether it does or not, the caller is able to increment the pointer itself by 
the appropriate amount, since it knows the data size.

e.g.

caller:

char*   ptrToCurrentData;

// assume the above points to some data at some arbitrary offset within a 
buffer. At this point we have to interpret part of the block
// as an array of doubles. The data must include some encoding about how big 
that block is or how many items it contains

int numberOfDoubles = <some means to determine the block size from the data 
itself, e.g. a subheader>

// at this point the caller can sanity-check the numberOfDoubles to make sure 
there's no buffer overrun, etc. The called function
// doesn't have any means to do that.

doStuffWithDoublesSubroutine((double*) ptrToCurrentData, numberOfDoubles );

// did the subroutine succeed? doesn't matter, move on to the next chunk:

ptrToCurrentData += ( sizeof(double) * numberOfDoubles );



Things might be different if your data is not parsable in this way, such as 
'keep going until you hit some marker or the end'. Even then it's often safer 
to lookahead to find the marker/end so you have a finite chunk to deal with, 
but if there's a chance that could be gigabytes away, it might be better to 
parse as you go. In that case returning a value indicating the number of items 
actually processed would allow the caller to calculate the offset for the next 
pointer, rather than rely on the called function to (correctly) do the pointer 
arithmetic for you as a side-effect.

Others might take another view, but I'd say keeping all your pointer arithmetic 
in one place is much easier to analyse and debug when it (inevitably) isn't 
correct - did anyone ever get pointer arithmetic absolutely spot on first time?

> But, basically you're right about the copy. This might be more canonical:
> 
> [foo point:NSMakePoint (* data, * (data + 1))];
> * data += dim;


well, double* is exactly the same as double[], so you can treat <data> as an 
array:

NSMakePoint( data[0], data[1])

which is usually more readable. That isn't a trick, it's an intentional feature 
of C.

I still wouldn't let the subroutine do the *data += dim though, when the caller 
can do it. If the caller really can't tell it how many to process in advance, 
arrange it to return a count of the number of items it did process as a return 
value, e.g:

int numProcessed = doStuffWithDoublesSubroutine((double*) ptrToCurrentData );
ptrToCurrentData = ( sizeof( double ) * numProcessed );

That way it's not a side-effect but a contractual obligation of the called 
function. But note that since the interior of this function can't see the whole 
buffer it's reading from, it has no way to stop instead of running off the end 
if the terminal condition is not met for some reason.

Hope this isn't too off-topic for Cocoa. If others take issue with my reasoning 
here I'd be interested to hear it - I just hate debugging stuff where the 
pointer arithmetic is all over the place.

--Graham





_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to