0

I reflecting about memcpy.

I know that memcpy is for copy a variable to variable.

But it is not better to use: (for ex.)

int a = 5;
int b;

b = a;

Instead memcpy ?

or use std::move instead memmove ?

  1. Memcpy and Memmove are not outdated/slowly functions (perhaps these functions are from C)?
  2. If yes, what is the best way to replace these functions in C++11 standard ?
Thomas Andrees
  • 251
  • 1
  • 3
  • 12
  • 3
    They are actually highly optimized functions for copying blocks of data. – T.C. Sep 15 '14 at 21:28
  • @T.C. these functions are not inherited from C to c++? Maybe C++ have a better way to replace that? - So i should use `memcpy` instead `b=a` ? – Thomas Andrees Sep 15 '14 at 21:29
  • 1
    Using `memcpy`/`memmove` instead of e.g. `=` or `std::copy` is premature optimisation. `memcpy`/`memmove` only works for POD types and should in general be avoided, except perhaps as a last resort when trying to optimise a code hotspot. – Paul R Sep 15 '14 at 21:29
  • 3
    `std::move` is not the C++ counterpart of `memmove`. `memmove` and `memcpy` are essentially the same function, except that the source and destination buffer may overlap in case of the former. In C++ you rely on the object's copy/move constructor for copying/moving. To copy a range of objects use `std::copy`, it's likely your standard library implementation will use `memcpy` under the hood if the objects are trivially copyable. Similarly, to move a range of objects, use the [`move`](http://en.cppreference.com/w/cpp/algorithm/move) that deals with ranges. – Praetorian Sep 15 '14 at 21:32
  • 2
    A typical Microsoft-inspired antipattern is to write `BLAHBLAH x; memset( &x, 0, sizeof(x));`. Instead write just `BLAHBLAH x = {};`. Safer, shorter, just as efficient. – Cheers and hth. - Alf Sep 15 '14 at 22:00
  • You should use `memmove` to copy items where the source or destination overlap. Use `memcpy` large blocks of data such that the overhead of calling `memcpy` is justified for the quantity of data. On the other hand, you should be passing large blocks of data by pointer or reference rather than copying them. – Thomas Matthews Sep 15 '14 at 22:02

2 Answers2

8

In order of decreasing importance, advantages are:

  • memcpy and memmove are type agnostic, so they can be used to bypass strict aliasing restrictions.

  • memcpy and memmove don't require alignment, although they probably run faster when data is aligned.

  • memcpy may be faster, since it can copy multiple elements at once. With the std::is_trivially_copyable type trait, though, std::copy should do this also.

Of course, they have the disadvantage of only working with trivially copyable types, and only with pointers, not iterators. But they have definite uses in C++ code, for example when pulling unaligned data out of network packets or blocks of files, or implementing approximations to floating-point functions using bit tricks.

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Adjusting the code to the unreasonable defaults of one particular compiler (g++, and its drop-in replacement dang) for the first point is in my humble opinion rather ungood. The last point, about efficiency, is the only one that's forced me to use `memcpy`. As it turns out, in practice the standard library C string copying implementation is often very slow compared to `memcpy`. I don't know why. – Cheers and hth. - Alf Sep 15 '14 at 21:56
  • 1
    @Alf: Those "unreasonable defaults" you speak of, come straight from the standards. I find in such cases it's best to move on to a new question that doesn't evoke my inner troll. – Ben Voigt Sep 15 '14 at 21:58
  • Re come straight from the standard", no that's not the case. The standard *allows* them, just as it allows gigabyte `bool` and much else silly impractical stuff. License to kill is not a directive to kill, even though James Bond sometimes seem to conflate the two. – Cheers and hth. - Alf Sep 15 '14 at 22:03
  • @Alf: The only unreasonableness is coming from people who refuse to admit that their broken code is, in fact, broken. The strict aliasing rule has been around for multiple standard revisions... the broken-code-writing horde has had the opportunity to present their case to remove it. Since there have been multiple Standards accepted since the optimization-induced-failures in broken code were well-known, I can only conclude that there is consensus among the standard committee and ballot countries to continue considering broken type punning code broken. – Ben Voigt Sep 15 '14 at 22:09
  • the term "strict aliasing" does not occur once in the standard, and I think you know that. not going to argue your value judgement of code that g++ fails to compile cleanly by default. ;-) – Cheers and hth. - Alf Sep 15 '14 at 22:13
  • 2
    @Alf: You're right. The verbiage in the Standard is "If a program attempts to access the stored value of an object through a glvalue of other than one of the following types **the behavior is undefined**". Somehow that doesn't give me feelings of less brokenness than gcc's error message about "strict aliasing". – Ben Voigt Sep 15 '14 at 22:28
  • this is not a new discussion. the next step is for me to mention that your cherished paragraph C++11 §3.10/10 requires UB for one case that C++11 §9.2/20 requires to be well-defined. i.e. there's an inconsistency, and it's been there since C++98. i'm pretty sure you know that too. if the length of presence in the standard counts as much as you argue it does, then it favors §9.2/20 just as much as §3.10/10. and so on. you can't win, you can only drown the issue. – Cheers and hth. - Alf Sep 15 '14 at 22:43
  • @Alf: It's now 9.2/18. But there's no conflict between the common initial subsequence rule and strict aliasing. lvalue-to-rvalue conversion takes place on the member type, which does indeed match. – Ben Voigt Sep 15 '14 at 22:46
  • possibly (IDK), but i'm referring to the "A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member [...] and vice versa" in C++ 9.2/20. C++11 §3.10/10 explicitly mentions one case but not the other. Thus there is a contradiction, and that list is necessarily incomplete, not exhaustive. – Cheers and hth. - Alf Sep 15 '14 at 22:58
-2

You are only considering one case. Nobody use memcpy and memmove for int variables.

They are basically highly optimized function to copy large blocks of data. They are the system functions. They directly deal with memory.

Arpit
  • 767
  • 7
  • 20