Consider the following code:
void MemMove8(void* dst, void* src)
{
char tmp[8];
memcpy(tmp, src, 8);
memcpy(dst, tmp, 8);
}
MSVC (16.7.1) x86 with /O2 generates the following assembly for this function:
; _dst$ = ecx
; _src$ = edx
mov eax, DWORD PTR [edx]
mov DWORD PTR [ecx], eax
mov eax, DWORD PTR [edx+4]
mov DWORD PTR [ecx+4], eax
But this doesn't work (in some cases) if the input and output buffers overlap.
The generated code seems wrong to me; or is this a valid transformation and I am missing something here?
You may observe that some VC++ library classes continue to use memcpy. Furthermore, you may observe that the VC++ compiler optimizer sometimes emits calls to memcpy. The Visual C++ product is developed in accordance with the SDL process, and thus usage of this banned function has been closely evaluated.
The memcpy and wmemcpy functions are only deprecated if the constant _CRT_SECURE_DEPRECATE_MEMORY is defined before the include statement, as in the example below: For more compatibility information, see Compatibility. See memmove for a sample of how to use memcpy.
The value of dest. memcpy copies count bytes from src to dest; wmemcpy copies count wide characters (two bytes). If the source and destination overlap, the behavior of memcpy is undefined. Use memmove to handle overlapping regions. Make sure that the destination buffer is the same size or larger than the source buffer.
If the source and destination overlap, the behavior of memcpy is undefined. Use memmove to handle overlapping regions. Make sure that the destination buffer is the same size or larger than the source buffer. For more information, see Avoiding Buffer Overruns.
It's a bug.
https://developercommunity.visualstudio.com/content/problem/1151407/incorrect-memcpy-optimization.html
This seems to have been fixed in VS 16.8.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With