2012-04-08 7 views
1

Gibt es einen Nachteil der Umwandlung von size_t zu lang? Weil ich ein Programm schreibe, das linked_list in einer Datei verwaltet. Also traversiere ich auf einen anderen Knoten basierend auf size_t und verfolge auch die Gesamtzahl der Listen als size_t. Daher wird es offensichtlich eine gewisse Umwandlung oder Addition von long und size_t geben. Hat das einen Nachteil? Wenn es dann soweit ist werde ich alles statt size_t machen, auch die Größen. Bitte beraten.Umwandlung von size_t in lang, Gibt es einen Nachteil?

+4

Das Konvertieren von 'size_t' in' long' ist ein Problem, wenn Sie einen 'size_t' Wert haben, der nicht in' long' passt. Hast du einen solchen Wert? Kannst du einen solchen Wert haben? – hvd

+0

Hmmmm, momentan nicht, aber ich könnte, wenn ich mich entscheide, die Größe der verknüpften Liste zu erhöhen. Ich denke daran, die Zählung so lange selbst zu halten. Weil die Variable, die vom Typ size_t ist, nur die Zählung behält, nehme ich an, int oder long werden den Job erledigen, was denkst du ??? – howtechstuffworks

+0

Eigentlich wird eine weitere Situation sein, ich bekomme den Wert von ofstream :: tlp(), der einen Ort zurückgibt, und ich werde die sizeof (long) hinzufügen, um zu einem anderen Ort zu traversieren, ist das in Ordnung? – howtechstuffworks

Antwort

1

Es ist jetzt kein Problem, aber es kann in Zukunft je nachdem, wo Sie Ihre App portieren werden. Das liegt daran, dass size_t so definiert ist, dass es groß genug ist, um Offsets von Zeigern zu speichern. Wenn Sie also einen 64-Bit-Pointer haben, ist size_t ebenfalls 64 Bits. Nun kann Long 64 Bit lang sein oder nicht, weil die Größenregeln für grundlegende Typen in C/C++ einigen Variationen Raum geben.

Aber wenn Sie diese Werte in eine Datei schreiben möchten, müssen Sie trotzdem eine bestimmte Größe wählen, es gibt also keine andere Option, als in lang konvertieren (oder lang, falls erforderlich). Besser noch, verwenden Sie einen der neuen Größen-spezifischen Typen wie int32_t.

Mein Tipp: Speichern Sie im Header Ihrer Datei die Größe des Typs, in den Sie size_t konvertiert haben. Wenn Sie sich in Zukunft dafür entscheiden, einen größeren zu verwenden, können Sie die alte Größe weiterhin unterstützen. Und für die aktuelle Version des Programms können Sie prüfen, ob die Größe unterstützt wird oder nicht, und einen Fehler ausgeben, wenn nicht.

+0

Sie haben Recht, das Szenario in meinem Programm werde Ich versuche, eine verknüpfte Liste in der Datei zu pflegen. Also muss ich das fill_offset notieren, zum Beispiel Rückgabewert von tellp(), tellg() in irgendwo, das ist hier 'lang'. Dann, wenn ich durchqueren muss, dann werde ich eine andere Variable haben size_t next_offset; wo next_offset berechnet wird, um den nächsten Datensatz zu erreichen. SO werde ich tun, (tellp() + next_offset); Hier wird next_offset als (sizeof (int) + sizeof (long) + sizeof (the_rest_of_the_values_in_the_node) berechnet und dann in einer Datei gespeichert. Gibt es einen besseren Weg das zu tun? PS: Ich sollte Boost/STL nicht verwenden – howtechstuffworks

+0

http: //stackoverflow.com/questions/10065323/how-to-collect-and-store-tellp-tellg-return-types verbundene Frage – howtechstuffworks

+2

Ein Vorschlag, den ich Ihnen geben würde, ist, all diese Logik, die Sie erwähnten, in eine Vorlagenklasse zu stellen, deren Parameter (nach Konvention, T) ist der Typ, der verwendet werden soll.Al die Arithmetik zum Konvertieren von Datensatznummern in Offsets sollte sizeof (T) innerhalb dieser Klasse verwenden, und alle Variablendeklarationen sollten T verwenden. Auf diese Weise haben Sie die Flexibilität, jeden Typ zu verwenden, ohne den Code ändern zu müssen Angesichts dieser Flexibilität können Sie beginnen, 32-Bit-Werte (uint32_t) zu unterstützen und die Größe im Dateiheader zu speichern.In Zukunft, wenn Sie 64 Bit unterstützen möchten, ist nur eine Frage der Instantiierung der Vorlage wieder. –

2

Gibt es einen Nachteil der Umwandlung von size_t zu lang?

Theoretisch lang kann kleiner sein als size_t. Außerdem ist lang signiert. size_t ist nicht signiert. Wenn Sie also beide im selben Ausdruck verwenden, wird sich Compiler wie g ++ beschweren. Viel. Theoretisch kann es zu unerwarteten Fehlern aufgrund von vorzeichenlosen Zuweisungen kommen.

offensichtlich wird, dass eine Umwandlung oder Zugabe von langen

Ich sehe nicht, warum soll es gibt einige Wandlungs- oder zusätzlich zu lang sein. Sie können size_t für alle arithmetischen Operationen verwenden. Sie können es als "ListIndex" oder was auch immer definieren und es im gesamten Code verwenden. Wenn Sie die Typen (long und size_t) mischen, wird g ++/mignw Sie zu Tode nerven.

Alternativ können Sie einen bestimmten Typ mit garantierter Größe auswählen. Neuere Compiler haben einen cstdint-Header, der Typen wie uint64_t enthält (es ist extrem unwahrscheinlich, dass Sie beispielsweise auf Dateien stoßen, die größer als 2^64 sind). Wenn Ihr Compiler den Header nicht hat, sollte er in Boost verfügbar sein.

2

Der "lange" Typ hat leider keine gute theoretische Grundlage. Ursprünglich wurde es auf 32-Bit-Unix-Ports eingeführt, um es von dem 16-Bit-Int zu unterscheiden, das von der existierenden PDP11-Software angenommen wird. Dann wurde später "int" auf diesen Plattformen auf 32 Bit geändert (und "kurz" wurde eingeführt) und "long" und "int" wurden zu Synonymen, die sie für eine sehr lange Zeit waren. Jetzt

, auf 64-Bit-Unix-ähnlichen Plattformen (Linux, die BSDs, OS X, iOS und was auch immer proprietäre Unix-Varianten Menschen immer noch über könnte Pflege) "long" ist eine 64-Bit-Größe. Aber, leider, nicht auf Windows: Es gab zu viel Legacy "Code" in den bestehenden Headern, die die Größe von (int) == sizeof (long) Annahme, so gingen sie mit einem Greuel namens "LLP64" und blieb lange als 32 Bits. Seufzer.

Aber "size_t" ist nicht so. Es hat immer genau eines gemeint: Es ist der Typ ohne Vorzeichen, der die native Zeigergröße im Adressraum speichert. Wenn Sie eine nicht signierte (!- Verwenden Sie ssize_t oder ptrdiff_t, wenn Sie arithmetische Zeichen mit Vorzeichen benötigen. Zeiger, der eine ganzzahlige Darstellung benötigt (d. h. Sie müssen die Speichergröße eines Objekts speichern). Dies ist, was Sie verwenden.

+0

Interessant. Ich höre oft Legacy als Grund, wenn es Dinge wie "es ist kein Fehler, sondern ein Feature" Probleme gibt. – howtechstuffworks

Verwandte Themen