Since binary +
is unsequenced, you need to enforce the desired ordering of evaluating the operands. Most of the time, printing individual digits means you want to print the MSD first, so you defer printing digits until you have established the MSD. This means you want to recurse first, and print while returning from the recursive calls.
If you want to keep your current code structure, you can use the comma operator, ,
, to sequence the two calls. To fix your dilemma, we detect when the input is a single digit.
ssize_t putuint_fdr(uintmax_t i, int fd)
{
ssize_t ret = 0;
return (i / 10 != 0
? ret = putuint_fdr(i / 10, fd),
ret + putc_fdr(i % 10 + '0', fd)
: putc_fdr(i + '0', fd));
}
This assumes write
does not return an error in the middle of printing your number. If you want to add additional robustness, you should try to account for that situation as well.
In a comment to this answer, you asked:
There is no way to don't use a variable and to keep sequenced calls? (the ret ssize_t
)
You need some sort of variable to add the result of two sequenced function calls. However, you can hide the assignment by passing the result of the first function call in as a parameter to the second function call.
ssize_t putc_fdr(char c, int fd, ssize_t ret)
{
return ret + write(fd, &c, sizeof(char));
}
ssize_t putuint_fdr(uintmax_t i, int fd)
{
return putc_fdr(i%10 + '0', fd,
i/10 ? putuint_fdr(i/10, fd) : 0);
}