Die Spezifikation der Funktion memmove()
ist, dass es Quelle und Ziel überlappend verarbeiten kann, aber die Spezifikation sagt nicht, dass memmove()
mit Zeigern auf die gerufen werden muss, gleicher Speicherblock ("Objekt" im Sprachgebrauch des Standards).
Wenn p1
und p2
Zeiger auf verschiedene Speicherblöcke sind, die Bedingung p2 < p1
ist undefinierten Verhalten. Der C99-Standard sagt (6.5.8: 5):
Wenn zwei Zeiger verglichen werden, das Ergebnis auf den relativen Stellen in dem Adressraum der Objekte darauf abhängt. Wenn zwei Zeiger auf Objekt oder unvollständige Typen beide auf das gleiche Objekt zeigen, oder beide hinter dem letzten Element desselben Array-Objekts liegen, dann vergleichen sie gleich. Wenn die Objekte, auf die verwiesen wird, Mitglieder desselben Aggregatobjekts sind, vergleichen Zeiger auf später deklarierte Strukturelemente größer als Zeiger auf zuvor in der Struktur deklarierte Elemente und Zeiger auf Arrayelemente mit größeren tiefgestellten Werten vergleichen größer als Zeiger auf Elemente des gleichen Arrays mit tieferen tiefgestellten Werten. Alle Zeiger auf Mitglieder desselben Union-Objekts vergleichen gleich. Wenn der Ausdruck P auf ein Element eines Arrays Objekt zeigt und der Ausdruck Q auf das letzte Element desselben Array-Objekts zeigt, vergleicht der Zeigerausdruck Q + 1 größer als P. In allen anderen Fällen ist das Verhalten nicht definiert .
Ich weiß nicht, ob das ist, worauf sich die Erklärung bezieht, aber es ist eine eindeutige Quelle der Nichttragbarkeit. Eine andere Implementierung könnte (uintptr_t)p2 < (uintptr_t)p1
verwenden. Dann ist der Vergleich <
ein Vergleich zwischen ganzen Zahlen. Die Konvertierung in.liefert implementierungsdefinierte Ergebnisse. Der Typ uintptr_t
wurde in C99 eingeführt und ist ein vorzeichenloser Integertyp, der garantiert die Darstellung eines Zeigers enthält.
Eine vollständig portierbare Implementierung von memmove()
könnte einen dritten Puffer für eine Zwischenkopie verwenden, oder use ==
comparison (die angegebene Ergebnisse in dem Kontext angibt, in dem sie verwendet werden müsste).
Gute Frage, lesen [Was bedeuten die Klammern um einen Funktionsnamen?] (Http://stackoverflow.com/questions/13600790/what-do-the-parentheses-around-a-function-name-mean/ 13600837 # 13600837) –
Vielen Dank, es war nützlich! – user926918