Was ist der Unterschied zwischen ssize_t und ptrdiff_t?

Lesezeit: 4 Minuten

Benutzeravatar von Jonathan Leffler
Jonathan Leffler

Der C-Standard (ISO/IEC 9899:2011 oder 9899:1999) definiert einen Typ ptrdiff_t in <stddef.h>.

Der POSIX-Standard (ISO/IEC 9945; IEEE Std 1003.1-2008) definiert einen Typ ssize_t in <sys/types.h>.

  • Was ist der Unterschied zwischen diesen Typen (oder warum wurden beide als notwendig erachtet)?
  • Gibt es eine Implementierung, bei der der zugrunde liegende Basistyp für ssize_t ist nicht dasselbe wie für ptrdiff_t?

  • vielleicht ist es die semantik von ptrdiff_t das forderte die Hinzufügung von ssize_t? Manchmal ist ein vorzeichenbehafteter Größentyp sinnvoll, wenn man ihn zwischendurch darstellen lassen möchte -1. Die Semantik von ptrdiff_t ist “Unterschied zwischen zwei Zeigern”, was nicht genau die Semantik von “Größe” ist.

    – Johannes Schaub – litb

    27. Dezember 2011 um 20:55 Uhr

  • Wahrscheinlich ein bisschen NIH-Paranoia in den zuständigen Stadards-Ausschüssen

    – Chris Dodd

    27. Dezember 2011 um 21:21 Uhr

Gibt es eine Implementierung, bei der der zugrunde liegende Basistyp für ssize_t nicht derselbe ist wie für ptrdiff_t?

x86-16 mit dem großen Speichermodell. Zeiger sind weit (32-Bit), aber einzelne Objekte sind auf ein Segment beschränkt (so size_t darf 16-Bit sein).

  • würde nicht ptrdiff_t in dieser Situation auch 16 Bit sein, da die Zeigerdifferenz nur dann definiert ist, wenn beide Zeiger auf dasselbe Objekt zeigen …

    – Chris Dodd

    27. Dezember 2011 um 21:15 Uhr

  • @Dhris: ptrdiff_t ist ein implementierungsdefinierter Typ, und es erscheint vernünftig, ihm die Größe eines Zeigers zu geben. Operationen auf Zeigern sollten niemanden überraschen, der mit dem Speichermodell und einem 16-Bit-Modell vertraut ist ptrdiff_t würde wahrscheinlich Leute überraschen, die 32-Bit-Zeiger verwenden.

    – David Thornley

    27. Dezember 2011 um 21:30 Uhr

  • @ChrisDodd: Ein Objekt kann bis zu 65535 Bytes groß sein, sodass eine gültige Zeigersubtraktion leicht 32767 überschreiten kann. zum ptrdiff_tmöchten Sie einen signierten Typ, der Werte bis zu 65536 enthalten kann.

    – Keith Thompson

    30. Dezember 2011 um 17:42 Uhr

  • Diese Antwort erscheint unvollständig, da die Antwort nicht diskutiert wird ssize_t.

    – chux – Wiedereinsetzung von Monica

    27. Februar 2015 um 18:24 Uhr

  • @KeithThompson C 6.5.6-9 lässt zu, dass die Zeigersubtraktion (von Zeigern in dasselbe Objekt) ptrdiff_t überläuft, wahrscheinlich genau aus diesem Grund. In einem relevanteren ILP32/Linux-System (wo alle drei Typen 32-Bit sind) könnten Sie zumindest theoretisch ein Objekt zuweisen, das 2 GB überschreitet, wobei das Subtrahieren von Zeigern darauf sowohl ptrdiff_t als auch ssize_t überlaufen würde

    – Dan Bonachea

    28. Dezember 2017 um 1:20 Uhr

Benutzeravatar von Adrian McCarthy
Adrian McCarthy

The Open Group Base Specifications Ausgabe 7, IEEE Std 1003.1, Ausgabe 2013, Beschreibung von <sys/types.h> sagt:

Der Typ ssize_t ist in der Lage, Werte mindestens im Bereich zu speichern [-1, SSIZE_MAX].

Mit anderen Worten, ssize_t ist unterschrieben, aber die Menge negativer Werte, die es darstellen kann, kann auf nur {-1} beschränkt sein.

EIN ptrdiff_tauf der anderen Seite, hat garantiert einen symmetrischeren positiven/negativen Bereich.

Ich gebe zu, dass dies in der Praxis nicht wahrscheinlich ist ssize_t wäre dies im negativen Bereich begrenzt, aber es ist möglich.

Ein weiterer Unterschied ist natürlich der ptrdiff_t ist verfügbar, wenn Sie in Standard-C oder C++ programmieren, aber ssize_t möglicherweise nicht verfügbar, es sei denn, Sie zielen auf ein Standard-POSIX-System ab.

  • Danke für die historischen Informationen; Es hilft zu erklären, woher es kommt, auch wenn der aktuelle Standard den Bereich nicht mehr vorschreibt. (Meine Suche nach dem aktuellen Standard war nicht das, was ich als endgültig ansehen würde, obwohl ich glaube, dass es ziemlich gründlich war; daher die „Wiesel-Wortlautung“ von „scheint nicht im Standard von 2008 zu sein“.)

    – Jonathan Leffler

    4. Juni 2012 um 17:36 Uhr

  • 2008 sys/types.h Standard hat das gleiche [-1, {SSIZE_MAX}] Voraussetzung für ssize_t.

    – jw013

    13. Juni 2012 um 12:40 Uhr

  • POSIX sagt das ssize_t ist ein ganzzahliger Typ, und der C-Standard verlangt, dass der maximale negative Wert von vorzeichenbehafteten ganzzahligen Typen mindestens so groß ist wie ihr maximaler positiver Wert.

    – MM

    8. März 2016 um 20:14 Uhr

  • @AdrianMcCarthy Siehe C11 6.2.6.2, in dem die zulässigen Bedeutungen für Bits innerhalb einer Ganzzahl erläutert werden. Der Begriff “vorzeichenbehaftete Ganzzahltypen” ist in 6.2.5 so definiert, dass er sowohl die standardmäßigen als auch die erweiterten vorzeichenbehafteten Ganzzahltypen umfasst.

    – MM

    8. März 2016 um 21:01 Uhr


  • @MM: Ah, Sie haben absolut Recht mit 6.2.6.2. Ich habe nichts dergleichen im C++-Standard gefunden (der weitaus weniger Treffer für “Integer-Typ” hat als der C-Standard). Die Sprache 6.2.5 sieht ungefähr genauso aus wie der C++-Standard, aber das schränkt die Darstellung oder den Bereich eines beliebigen Integer-Typs nicht ein. Vielen Dank!

    – Adrian McCarthy

    8. März 2016 um 21:55 Uhr

1410310cookie-checkWas ist der Unterschied zwischen ssize_t und ptrdiff_t?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy