Спецификация функции memmove()
заключается в том, что она может обрабатывать перекрывающиеся источник и место назначения, но в спецификации не говорится, что memmove()
должна вызываться с указателями на один и тот же блок памяти («объект» на языке стандарта).
Когда p1
и p2
являются указателями на разные блоки памяти, условие p2 < p1
является неопределенным поведением. Стандарт C99 гласит (6.5.8:5):
При сравнении двух указателей результат зависит от относительного расположения в адресном пространстве объектов, на которые они указывают. Если два указателя на объект или неполные типы оба указывают на один и тот же объект или оба указывают на один после последнего элемента одного и того же объекта массива, они сравниваются равными. Если объекты, на которые указывают объекты, являются членами одного и того же агрегатного объекта, то указатели на элементы структуры, объявленные позже, сравниваются лучше, чем указатели на элементы, объявленные ранее в структуре, а указатели на элементы массива с большими значениями нижнего индекса сравниваются больше, чем указатели на элементы того же массива. с более низкими значениями индекса. Все указатели на члены одного и того же объекта объединения равны. Если выражение P указывает на элемент объекта массива, а выражение Q указывает на последний элемент того же объекта массива, выражение указателя Q+1 сравнивается больше, чем P. Во всех остальных случаях поведение не определено.
Я не знаю, к чему относится объяснение, но это один из определенных источников непереносимости.
Другая реализация может использовать (uintptr_t)p2 < (uintptr_t)p1
. Тогда сравнение <
является сравнением целых чисел. Преобразование в uintptr_t
дает результаты, определенные реализацией. Тип uintptr_t
был введен в C99 и представляет собой целочисленный тип без знака, который гарантированно содержит представление указателя.
Полностью переносимая реализация memmove()
может использовать третий буфер для хранения промежуточной копии или использовать ==
сравнение (которое дает указанные результаты в том контексте, в котором оно должно быть использовано).
person
Pascal Cuoq
schedule
26.10.2013