webentwicklung-frage-antwort-db.com.de

Was sind die Nutzungsunterschiede zwischen size_t und off_t?

Abgesehen von der Größe der Werte, die jeder Typ enthalten kann, sind die Hauptunterschiede in usage zwischen size_t und off_t? Ist es nur eine Konvention, dass size_t-Typen für absolute Größen und off_t-Typen für Offsets verwendet werden? Oder geht es tiefer als das?

Ich schreibe eine Wrapper-Klasse, um das Schreiben großer Dateien mit mmap zu ermöglichen, und ich möchte wissen, welche Typen für ihre Argumente am besten geeignet sind. Da ich in Dateien mit mehr als 4 GB schreiben möchte, bin ich versucht, size_t für alles zu verwenden, aber ist dies die beste Vorgehensweise? (oder sollte ich für bestimmte Funktionen einige off64_t-Typen verwenden?)

Zum Beispiel sollte meine writeAt-Funktion folgendermaßen deklariert werden:

MMapWriter::writeAt(off64_t offset, const void* src, size_t size)

oder

MMapWriter::writeAt(size_t offset, const void* src, size_t size)
36
Lee Netherton

size_t ist für Objekte, off_t ist für Dateien.

mmap führt die beiden Konzepte zusammen, sozusagen per Definition. Ich persönlich denke, ich würde size_t verwenden, da eine zugeordnete Datei, egal was es ist, auch ein Array im (virtuellen) Speicher ist.

size_t ist Standard C++, off_t ist Posix und off64_t ist eine GNU Erweiterung, die zu den Funktionen fopen64, ftello64, gehört. usw. Ich denke sollte immer derselbe Typ sein wie off_t auf 64-Bit GNU Systemen, aber setzen Sie Ihr Unternehmen nicht darauf ohne zu prüfen.

Wenn dies relevant ist, ist off_t signiert, während size_t nicht signiert ist. Das signierte Gegenstück zu size_t ist jedoch ptrdiff_t. Wenn Sie also einen signierten Typ benötigen, bedeutet das nicht automatisch, dass Sie off_t oder off64_t verwenden sollten.

48
Steve Jessop

size_t ist Teil der C++ - (und C-) Standards und bezieht sich auf den Typ eines sizeof-Ausdrucks. off_t wird durch den Posix-Standard definiert und bezieht sich auf die Größe einer Datei.

12
James Kanze

Gute Faustregel für dieses Szenario. Verwenden Sie die Funktionssignatur, die dazu führt, dass Sie die geringste Menge an expliziten Castings verwenden, entweder im C-Stil oder im C++ - Stil. Wenn Sie eine Besetzung durchführen müssen, ist der C++ - Stil sicherer, da er in den Besetzungsarten eingeschränkter ist.

Der Vorteil davon ist, wenn Sie auf eine Plattform portieren, auf der die Typen nicht übereinstimmen (z. B. signierte Probleme, Größen- oder Endianitätsprobleme usw.), sollten Sie die meisten Fehler zur Kompilierzeit und nicht zur Laufzeit beheben. Casting ist der Vorschlaghammer-Ansatz, um ein dreieckig geformtes Objekt in ein rundes Loch zu quetschen (mehr oder weniger, wenn Sie dem Compiler sagen, er soll ruhig bleiben, ich weiß, was ich mache).

Der Versuch, Casting-Probleme zur Laufzeit zu finden, kann schwierig sein, da sie sich nur schwer reproduzieren lässt. Es ist besser, Probleme zur Kompilierzeit als zur Laufzeit zu finden. Der Compiler ist dein Freund.

0
ericcurtin