2

I have a code like

while (n--)
{
  *((char*)dest++) = *((char*)src++);
}

where dest and src are void pointers and n a size. The goal is to re-implement a memcpy function. When compiling this code with gcc, everything works great, but when I add the -Wpedantic flag I have four warnings "wrong type argument to increment".

Google tells me that it happens when trying to use arithmetic on void pointers, because gcc treats void type as being a 1 byte type in this case, but legacy compilers shoud not. I then have to cast the pointer to a char pointer but as you can see I already did it!

Any idea?

Thüzhen
  • 183
  • 6

1 Answers1

4

Casting (void) dest and src to unsigned char * before you use them gives the cleanest code (at the cost of two pointer variables on the stack).

unsigned char * dest_p = (unsigned char *)dest;
unsigned char * src_p  = (unsigned char *)src;

while ( n-- )
{
    *dest_p++ = *source_p++;
}

(Why unsigned? Because that's how the standard explicitly defines it. ;-) )

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • Yes, you are right, in fact I copied the just a part of the code where I verify that the data I have to copy is word-aligned, if not I use char type. I will fix it now in the post. – Thüzhen Sep 25 '14 at 08:00
  • 1
    the ++ has a higher precedence than the cast, so the increment goes to the void pointer, which is not allowed – mch Sep 25 '14 at 08:04
  • @Thüzhen: Adapted answer to fit your edit. Sorry, I thought the *reason* for the warning was somewhat obvious... ;-) – DevSolar Sep 25 '14 at 08:05
  • Why `*(((long*)dest)++) = *(((long*)src)++);` does not work then? – Thüzhen Sep 25 '14 at 08:05
  • @Thüzhen: Because you're doing arithmetics on a temporary? – DevSolar Sep 25 '14 at 08:06
  • Oh, you mean that since I do the cast in the loop, the casted variable is temporary (and "dies" at the end of the loop) and thus does not hold the incremented value? – Thüzhen Sep 25 '14 at 08:09
  • @Thüzhen: No. I mean that `((long*)dest)` is not an lvalue ("temporary" is perhaps the wrong word here, I'm not sure about the exact language lawyer legalese on this point). You can `dest++`, and you can `dest_p++` (in my code example), but you cannot `++` a *cast* pointer. – DevSolar Sep 25 '14 at 08:12