Reputation: 308
A few posts compare the performance between C++-style functions std::copy, std::equal, std::fill
with C-style functions std::memcpy, std::memcmp, std::memset
, for example :
But I haven't found what justifies the replacement by these new functions over the old one from a practical point of view. Of course, the list of functions is not exhaustive.
What are the practical advantages of these new versions ?
If performance is not a criterion for choosing, is it desirable (time permitting) to replace all occurrences of these C-style functions with the C++ versions ?
I tried to understand why some functions have been introduced in c++
and if it is necessary to do the replacement.
Upvotes: 0
Views: 921
Reputation: 62531
But I haven't found what justifies the replacement by these new functions over the old one from a practical point of view.
These functions are more general. memcpy
and memset
are only defined for contiguous ranges of types that are TriviallyCopyable, and memcmp
is (generally) only meaningful for contiguous ranges of TriviallyCopyable types with no padding. N.b. a single object is vacuously a contiguous range of length one.
Performance is only comparable when they do the same things, and by the as-if rule, an implementation can choose to implement a call to std::copy
in exactly the same way as it does memcpy
when it can prove the ranges don't overlap, or memmove
otherwise. Similarly std::fill
with memset
and std::equal
with memcmp
1.
Upvotes: 1
Reputation: 153889
As has been pointed out in the comments, std::copy
, etc. work, where as std::memcpy
, ect. only work in a very limited number of cases. In particular, std::memcpy
doesn't work for anything with an non-trivial constructor, so for none of the standard containers. Even when used on a C style struct
, or a C style array of struct
s, it only does a shallow copy, so depending on the semantics of the object, it may not work even on a C style struct
which contains a pointer.
With regards to performance, nothing is of course guaranteed. But the compiler will have access to the source of std::copy
(because it is a template), and will typically be able to inline it -- for C style struct
s, this would usually result in copying in larger chunks (machine words, rather than bytes). In the case of std::memcpy
, there is typically a function call, which hides any information about the underlying context, and requires either a byte-wise copy (resulting a lot more times in the loop), or complicated logic for handling alignment and a possible odd number of bytes. The C standard does allow memcpy
to be a macro, resolving to a special symbol which triggers some sort of compiler optimization, but I don't think this is legal in C++. And some earlier, pre-(C)standard C compilers did recognize memcpy
as if it were a keyword, in order to generate inline code. But this is all in the very distant past (before the first C standard).
In today's C++ code, there is absolutely no reason to use std::memcpy
, ever.
Upvotes: 3
Reputation: 122133
memset
has two drastic limitations.
First the container. You can only memset
more than a single element to a container that uses contiguous memory. It can work for std::array
or std::vector
but not for most other containers.
Next, the elements. You can only memset
trivially copyable objects. Already something as "simple" as std::string
is not trivially copyable.
memset
can be used in some cases. The other functions you mention are more generally applicable and when they can be replaced by memset
the compiler can do that.
Upvotes: 2