Re: Pass-by value… warning (was: NSTextField fieldeditor subclass example? (and an unrelated other inquiry))
Re: Pass-by value… warning (was: NSTextField fieldeditor subclass example? (and an unrelated other inquiry))
- Subject: Re: Pass-by value… warning (was: NSTextField fieldeditor subclass example? (and an unrelated other inquiry))
- From: Graham Cox <email@hidden>
- Date: Wed, 7 Jul 2010 21:52:44 +1000
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@hidden)
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:
This email sent to email@hidden