Являются ли ограничения 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 - много данных, чтобы испортить целевой диапазон, если он перекрывается с исходным, особенно учитывая, что ЦП не дает обещаний об относительном порядке индивидуальной загрузки и магазинов.

Другие вопросы по тегам