void *my_memcpy(void *dst, const void *src, size_t n)
{
const uint8_t *s = src;
uint8_t *d = dst;
for (size_t i = 0; i < n; i += 1) d[i] = s[i];
return dst;
}
int powi(int x, int y)
{
int result = 1;
for (int i = 0; i < y; i += 1) result *= x;
return result;
}
For itoa, I experiment with the comma operator to show the post-increment on the same line, but visibly after. I also move the negation sign block to the absolute value block. void itoa(int n, char s[])
{
int i = 0;
if (n < 0){
n = -n;
s[0] = '-', s += 1; // exclude from reverse
}
do{
s[i] = n % 10 + '0', i += 1;
n /= 10;
}while(n > 0);
s[i] = '\0';
// reverse
for(int j = 0, hi = i / 2; j < hi; j += 1) {
i -= 1;
char swap = s[j];
s[j] = s[i];
s[i] = swap;
}
}
Test code: #include <stdio.h>
#include <stdint.h>
// insert functions
int main(void){
char src[] = "hello";
char dst[10];
my_memcpy(dst, src, sizeof(src));
printf("%s == hello\n", dst);
printf("%d == 27\n", powi(3,3));
itoa(-12345, dst);
printf("%s == -12345\n", dst);
itoa(0, dst);
printf("%s == 0\n", dst);
}The other side effect expression here is the equals operator; once again, this should not be an expression but should just be a statement. Once again this is used (intentionally) mainly for compactness and unintentionally used to create messy bugs. I do find the "yoda" style checks to be aesthetically unpleasing so I'm party of the problem here.
Maybe it's time to add `-Wno-crement-expressions` and `-Wno-assignment-expressions`. `-Wparentheses` gets you part of the way to the second but even the legitimate uses are ugly to my eye.
Aren't there static analyzers in widespread use that would catch these?