Bug 163691 - Use std::copy() instead of memcpy()
Summary: Use std::copy() instead of memcpy()
Status: UNCONFIRMED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Writer (show other bugs)
Version:
(earliest affected)
unspecified
Hardware: All All
: medium normal
Assignee: Not Assigned
URL:
Whiteboard:
Keywords: difficultyBeginner, easyHack, skillCpp, topicCleanup
Depends on:
Blocks: Dev-related
  Show dependency treegraph
 
Reported: 2024-10-30 17:33 UTC by Hossein
Modified: 2024-10-31 06:14 UTC (History)
1 user (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hossein 2024-10-30 17:33:19 UTC
Description:
In LibreOffice core, there are many places where a block of memory is copied from one place to another. In this case, two functions are used:

1. Older C style memcpy(), which is defined in <string.h> (alternatively <cstring>) and is used as:

memcpy( to, from, count ); // to and from are void* pointers
https://en.cppreference.com/w/cpp/string/byte/memcpy

2. Newer C++ style std::copy, which is defined in <algorithm> and is used with pointers and iterators as:

std::copy( from, from + size, to ); // pointers
std::copy( from_iter_first, from_iter_last, to_iter_first ); // iterators
https://en.cppreference.com/w/cpp/algorithm/copy 

The goal here is to refactor the code and replace the usages of memcpy() with equivalent std::copy().

Finding instances:
You can find instances of memcpy() usage in C++ code with:

$ git grep -w memcpy *.hxx *.cxx

Currently there are 720 instances of using memcpy in the code.

Notes:
1. Correctly setting the parameters is important, as they are different in std::copy() and memcpy().

2. You have to make sure that the code behavior does not change with your patch. If classes with user-defined copy constructor are used instead of basic data types, you have to make sure that std::copy which invokes copy constructor does not make any difference.

Example:
You can see the two std::copy() calls (commented) equivalent to memcpy() in this code snippet:

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>

int main()
{
        std::vector<int> from {1,2,3,4,5}, to(5);

        std::memcpy(to.data(), from.data(), 5 * sizeof(int));
//      std::copy(from.data(), from.data() + 5, to.data());
//      std::copy(from.begin(), from.end(), to.begin());

        for (int num : to)
                std::cout << num << " ";
        std::cout << "\n";

        return 0;
}
Comment 1 Mike Kaganski 2024-10-31 05:15:06 UTC
Also, memmove (usable with overlapping memory) may be replaced with either std::copy (when end of dest range is inside of source range, i.e. copying to the left), or std::copy_backward (when start of dest range is inside of source range, i.e. copying to the right).

Note also, that e.g. cppreference states, that "implementations of std::copy ... use bulk copy functions such as std::memmove", so not perfectly identical to memcpy, which can't work on overlapping ranges, but is most efficient.