views:

181

answers:

3
+2  A: 

Your inner function should copy count + 1 bytes, e.g.,

 do /* copy one byte */ while(count-- != 0);

If the post-decrement is slow, other alternatives are:

 ... /* copy one byte */
 while (count != 0) { /* copy one byte */; count -= 1; }

or

 for (;;) { /* copy one byte */; if (count == 0) break; count -= 1; }

The caller/wrapper can do:

if (count > 0 && count <= 256) inner((uint8_t)(count-1))

or

if (((unsigned )(count - 1)) < 256u) inner((uint8_t)(count-1))

if its faster in your compiler.

Doug Currie
You can wrap this in a macro so that the exported interface is sane.
Nathon
A: 

If an int parameter costs 3 instructions and a char parameter costs 1, you could pass an extra char parameter for the extra 1 bit you're missing. It seems pretty silly that your (presumably 16-bit) int takes more than twice as many instructions as an 8-bit char.

Nathon
The compiler will allow one char parameter to be passed in the W register; all other parameters have RAM locations allocated to them. In many cases, it would be advantageous if the compiler could pass the LSB of a word parameter in W, but it doesn't. Actually, if I were designing a compiler, I would probably specify that every function that doesn't accept a char but does take a word would have two entry points; one entry point would store W to the LSB and then fall through to the other. Other routines could call whichever one was most advantageous.
supercat
That's nuts. I thought PICs were supposed to be RISCy. Oh well.
Nathon
A: 

FWIW, I'd choose some variant of option #1. The function's interface remains sensible, intuitive, and seems less likely to be called incorrectly (you might want to think about what you want to do if a value larger than 256 is passed in - a debug-build-only assertion might be appropriate).

I don't think the minor 'hack'/micro-optimization to loop the correct number of times using an 8-bit counter would really be a maintenance problem, and it seems you've done considerable analysis to justify it.

I wouldn't argue against wrappers if someone preferred them, but I'd personally lean toward option 1 ever-so-slightly.

However, I would argue against having the public interface require the caller to pass in a value one less than they wanted to read.

Michael Burr
@Micnael Burr: Supplying the actual number of bytes to process, whatever that may be, "feels" right, though I hate wasting code space. Certainly it has a better "feel" than passing n-1. It might not be unreasonable to handle an arbitrary number of bytes, even though I don't expect any buffers larger than 256 bytes. Some routines like blank-check-range could well be used with counts larger than 256 bytes, and if the inner loop only uses an 8-bit variable, the cost of accepting a larger one wouldn't be huge. I'll post some further thoughts above.
supercat