Являются ли ограничения std::copy более смягченными, чем std::memcopy?
Что касается проблем, связанных с копией против memcpy и memmove (отличная информация здесь, между прочим), я читал, и мне кажется, что в отличие от того, что говорится в разговорной речи, например, в cppreference Примечание: memcpy был изменен на с момента принятия этой цитаты. -
Заметки
На практике реализации
std::copy
избегайте многократных назначений и используйте функции массового копирования, такие какstd::memcpy
если тип значенияTriviallyCopyable
- std::copy
(ни std::copy_backward
) не может быть реализовано с точки зрения memcopy
, потому что для std::copy
только начало диапазона назначения не должно попадать в исходный диапазон, но для memcpy
все диапазоны не должны пересекаться.
Рассматривая реализацию Visual-C++ (см. xutility
заголовок), мы также можем заметить, что VC++ использует memmove, но теперь у него более строгие требования, чем std::copy
:
... Объекты могут перекрываться: копирование происходит так, как если бы символы были скопированы во временный массив символов, а затем символы были скопированы из массива...
Так что казалось бы, что реализация std::copy
с точки зрения memcpy
не возможно, но используя memmove
на самом деле пессимизация. (крошечная пессимизация, возможно, не измеримая, но все же)
Возвращаясь к вопросу (ам): верно ли мое резюме? Это где-нибудь проблема? Независимо от того, что указано, возможна ли даже практическая реализация memcpy
это также не соответствует требованиям std::copy
есть memcpy
реализации, которые ломаются, когда диапазоны частично перекрываются, как это разрешено std::copy
?
1 ответ
Если вопрос в том, возможно ли встретить эффективную реализацию memcpy с достаточным неопределенным поведением, чтобы не доверять ей в перекрывающихся диапазонах, тогда ответ - да.:-)
Рассмотрим одну из возможных реализаций memcpy on Power(PC): инструкция lmw загрузит несколько последовательных слов из памяти в последовательные регистры (которые могут быть указаны в качестве заданного пользователем аргумента диапазона). Затем stmw сохранит введенный диапазон регистров обратно в память. Таким образом, мы говорим о ~100/200 байт (32b/64b ЦП), буферизованных ЦП во время одной итерации memcpy - много данных, чтобы испортить целевой диапазон, если он перекрывается с исходным, особенно учитывая, что ЦП не дает обещаний об относительном порядке индивидуальной загрузки и магазинов.