Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does wmemcpy exist when memcpy should suffice?

Tags:

c

memcpy

wmemcpy appears to perform the same operations as memcpy but accepts wchar_t* instead of void*. How is its existence justified if these two code snippets should have the same behaviour? Does it have a useful purpose?

memcpy(dest, wchar_array, sizeof(wchar_array));

And

wmemcpy(dest, wchar_array, sizeof(wchar_array) / sizeof(wchar_t));
like image 785
Jordan Melo Avatar asked Apr 07 '16 21:04

Jordan Melo


2 Answers

In addition to davmac's answer about API symmetry and having the size of an array not always granted, it should be emphasized that the third argument of wmemcpy refers to number of elements to copy (rather than bytes).

If you work with wchar_t objects and handle them with other functions from <wchar.h>, it may facilitate matters. wcslen for instance returns the C wide string length in terms of wchar_t elements, and wcschr and wcsrchr return wchar_t *, thus using them to do some pointer arithmetic also keeps you in the "realm" of number-of-elements.

P.S. If the size of the minimal wchar_t array is given as implied in your example, using wmemcpy may result in more elegant code than that sizeof(wchar_array) you used:

#define SIZE 40
wchar_t wchar_array[SIZE];
// ...
wmemcpy(dest, wchar_array, SIZE);
like image 155
R.G. Avatar answered Nov 15 '22 18:11

R.G.


I guess it's largely about API symmetry, but also, it allows more easily writing code which can work with both wide character and normal strings (switched over by a preprocessor define or similar).

Essentially, if you want your code to work with char, you #define your copy function as memcpy. For wchar_t, you define it as wmemcpy instead. Your size argument is just the number of characters (either char or wchar_t); remember that the argument isn't necessarily a fixed size array, so using sizeof isn't always an option.

The Win32 API for instance makes use of a similar strategy: If you define the UNICODE preprocessor symbol, most functions resolve to their wide-character version (suffixed with W) but otherwise they resolve to the "narrow" character version (suffixed with A); TCHAR is defined as either char or wchar_t accordingly; etc. The upshot is you can write code which works with either wide or regular characters fairly easily.

Of course, this is in no way necessary; but then, the standard C library isn't necessarily supposed to be absolutely minimal. You could argue that calloc is superfluous since you can always use malloc and then memset, for instance; it still exists, however.

like image 24
davmac Avatar answered Nov 15 '22 19:11

davmac