2

I read the article Optimizing Memcpy improves speed, I have a question about the modified-GNU algorithm, I get an error running the code the src & 0xFFFFFFFC , src is a void pointer, can it be a left operand for ‘&’ ? Did I miss anything here?

Thanks

Error 1 error C2296: '&' : illegal, left operand has type 'const void *’

void * memcpy(void * dst, void const * src, size_t len)
{
    long * plDst = (long *) dst;
    long const * plSrc = (long const *) src;
    if (!(src & 0xFFFFFFFC) && !(dst & 0xFFFFFFFC))
    {
        while (len >= 4)
    {
            *plDst++ = *plSrc++;
            len -= 4;
        }
    }
    char * pcDst = (char *) plDst;
    char const * pcSrc = (char const *) plSrc;
    len += 4;
    while (len--)
    {
        *pcDst++ = *pcSrc++;
    }
    return (dst);
}
1
  • You know, GCC on a PC for one understands the basic memcpy definition well enough that it'll emit code to write longs at a time, and double-longs if you tell it it can use MMX. Commented Jul 9, 2010 at 7:07

3 Answers 3

1

You can bitmask pointers - it is a legitimate operation if you know what you are doing.

First off, make sure your compiler is not in C++ mode (since it appears you are using MSVC++) - this should be a warning in C, not an error.

Second, 0xFFFFFFFC is an integer - you should make the appropriate cast for the operation in question (make it a pointer type).

Third, I would expect your compiler/libc already has a fantastic implementation of memcpy - use the built in one, not your own version. Compilers do perform some trickery with C and standard library functions, and may even inline and unroll memcpy loops. When you make your own memcpy, this trickery is usually not done.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks theatrus, i just want to find a more efficient way to do the data transfer using memcpy and i think it make no sense to do src & 0xFFFFFFFC.
The idea is to align writes on 32-bit boundaries.
To further these comments: writes aligned on 32-bit boundaries are often much faster than writes that are not. Writing an aligned 32-bit chunk is often much faster than writing the 4 bytes individually. This all depends on processor, here, we're likely meaning some x86 based thing, though this holds true for many (just not necessarily all) architectures.
1

Not sure how this went unanswered for so long. The C standard really couldn't be clearer on this point C99 §6.5.10 (Bitwise AND operator):

Constraints

Each of the operands shall have integer type.

Thus, you need to cast the pointers to integers before they can be used as operands of &; specifically, you should cast them to intptr_t (or uintptr_t), for which the standard guarantees "that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer"

#include <stdint.h>
...
if ((intptr_t)src & 3) {
   // src does not have 4 byte alignment
}

There are some other issues with your code, but adding the casts will let you move on to finding those.

Comments

0

I read a similar article at http://www.eetimes.com/design/embedded/4024961/Optimizing-Memcpy-improves-speed/ and the part that seems wrong to me is that

if (!(src & 0xFFFFFFFC) && !(dst & 0xFFFFFFFC))

does not check for aligned pointers.

for example, if src is 0x13 (odd), then src & 0xFFFFFFFC is 0x10. !(0x10) is 0, so the if fails. fine.

if src is aligned, say 0x14, then src & 0xFFFFFFFC is 0x14. !(0x14) is 0, so the if fails. oops.

I would think this is the appropriate check:

if (!(src & 0x3) && !(dst & 0x3)) {
   // pointers are aligned, copy in 32 bit chunks
   ....
}

and I also don't see the purpose in len += 4; but i guess the original question was just about a compile error, so this whole response is somewhat a digression, and maybe i've misunderstood how it is supposed to work. (and I agree with the original answer, just use what comes in the library).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.