unsigned long ul1=XX, ul2=YY, ul; unsigned int ui1=AA, ui2=BB, ui; ui=ui1+ui2; ul=ul1+(ul2+(unsigned long)CY);
"You have access to the carry bit in the program status word register." True, but you have no guarantee that the carry bit at the start of a 'C' statement will necessarily have anything to do with the result of any particular arithmetic operation in the preceding 'C' statement. If you need that sort of direct register control, then you must write in assmebler!
True; the only reason that the variable "c" exists is to try to snag the carry flag before later ADDs in the loop control code change it. And the success of that scheme, of course, is highly dependent on your code generator. You'll be looking at the assembly output anyway; might as well just write the routine in assembler to start with. Another way to tackle the problem is to do the U8 addition in a U16, so you wind up with the carry bit in an actual C variable, instead of relying on quirks of the compiler and architecture:
void U48AddEq (U8 data* dst, U8 data* src, U8 len) { U16 temp = 0; while (len--) { temp += dst[len] + src[len]; dst[len] = (U8)temp; temp >>= 8; } }