Typ size_t beim Überschreiben von new
-
FlashBurn schrieb:
Ich hasse es wenn man für jeden Compiler eigene Sachen definieren muss (solche ifdef´s machen den Code nicht gerade lesbarer). Wieso kann sowas nicht in dem Standard sein?
Makros (und eben die dazugehörigen Anweisungen (
#undef,#ifdef, ...)) sind standardisiert.
-
FlashBurn schrieb:
Also im Endeffekt zeigt das mal wieder das weder C noch C++ wirklich plattformunabhängig sind
Falsch. Das zeigt exakt das Gegenteil. Wäre im C++ Standard eine exakte Größe für Datentypen festgelegt, dann wird der Code auf bestimmten Mikroprozessoren nicht laufen. Du darfst eben nicht beide Sprachen als PC-Only Sprachen sehen, wie das z.B. bei Java der Fall ist. C/C++ ist mehr.
FlashBurn schrieb:
und das es ohne den Compiler zu beachten nicht möglich ist bestimmten Code (z.B. die C++ Standard-Library) zu schreiben. Spricht nicht gerade für die Sprachen

Naja, einen Code mit falscher Syntax wirst du wohl nicht unbedingt kompilieren wollen, oder?
FlashBurn schrieb:
Ich hasse es wenn man für jeden Compiler eigene Sachen definieren muss (solche ifdef´s machen den Code nicht gerade lesbarer). Wieso kann sowas nicht in dem Standard sein?
Musst du nicht. Habe ich z.B. noch nie gebraucht. Aber stell dir vor, das gibts bereits. http://en.wikipedia.org/wiki/Stdint.h
-
volkard schrieb:
FlashBurn schrieb:
@volkard
Seit wann ist denn int immer 4Byte und long je nach Architektur? Ich habe es noch genau anders herum gelerntZu meiner großem Enttäuschung haben sich die Entwickler von MSVC und GCC dahingehend geeinigt.
Ich dachte immer bei MSVC sind
intundlongimmer 4 Byte undlong longimmer 8, unabhängig vonsizeof(void*).Und nur bei GCC gilt
sizeof(long) == sizeof(void*)...Hat sich da was geändert?
Dann müssten wir alle unsere Windows-Programme umschreiben
-
hustbaer schrieb:
Ich dachte immer bei MSVC sind
intundlongimmer 4 Byte undlong longimmer 8, unabhängig vonsizeof(void*).Und nur bei GCC gilt
sizeof(long) == sizeof(void*)...Hat sich da was geändert?
Dann müssten wir alle unsere Windows-Programme umschreiben
Hast recht.
Hab auch falsche Bücher gelesen.
-
314159265358979 schrieb:
Wäre im C++ Standard eine exakte Größe für Datentypen festgelegt, dann wird der Code auf bestimmten Mikroprozessoren nicht laufen.
Das musst du mir erklären.
Ich sehe es genau umgedreht, wenn der Datentyp den ich gewählt habe mit einmal kleiner ist, dann läuft mein Programm auf der Architektur nicht mehr. Wären die Datentypen genau spezifiziert, gäbe es solche Probleme nicht (und wozu haabn C/C++ eigentlich mehrere Datentypen für den selben Zahlenbereich?).
Es wäre viel besser wenn es für jeden Zahlenbereich genau einen Typen geben würde und der wäre genau festgelegt, da gäbe es dann keine Gründe warum man mit sowas aufpassen muss wenn ein Programm z.B. von 32bit auf 64bit portiert wird!
314159265358979 schrieb:
Du darfst eben nicht beide Sprachen als PC-Only Sprachen sehen, wie das z.B. bei Java der Fall ist. C/C++ ist mehr.
Wieso sollt Java PC-only sein? Java läuft auf jeder Architektur wo man ne VM dafür hat (und ich möchte meinen auch schon was von Java auf Mikrokontroller gehört zu haben).
314159265358979 schrieb:
Habe ich z.B. noch nie gebraucht. Aber stell dir vor, das gibts bereits.
Aber irgendjemand muss ja die Library schreiben. Zumal damit die "Standard"-Libraries nicht Compiler unabhängig sind (ohne die ifdef´s).
Aber keiner konnte mir nun sagen wer recht hat (bezüglich welchen Typ von Parameter new erwartet) clang oder gcc?
-
FlashBurn schrieb:
Aber keiner konnte mir nun sagen wer recht hat (bezüglich welchen Typ von Parameter new erwartet) clang oder gcc?
Ähm, size_t und clang und gcc widersprechen sich dahingehend gar nicht?
-
Der Compilerbauer entscheidet selbst, welchen Typ
operator newerwartet. Den musst du aber nicht wissen. Um platformunabhängigr Programme zu ermöglichen ist genau für diesen Typ eintypedefstandardisiert:size_t.Die Intension, für die Standardtypen keine festen Größen vorzuschreiben, hat übrigens Performancegründe. So sollte
intursprünglich genau ein Maschienenregister groß sein, so dass es also Mittel der Wahl ist, wenn man im beschränkten Wertebereich optimal schnell rechnen will. Braucht man feste Größen gibt es immer nochint32_t,int32_least_t,int32_fast_tetc. Leider haben sich im Laufe der Zeit so viele Programmierer und Programme ansizeof(int) == 4gewöhnt, das man aus Gründen der Abwärtskompatibilität unter x64intnicht einfach auf 8 Byte setzen konnte.
-
Aber size_t ist unterschiedlich definiert und das dürfte ja eigentlich auch nicht sein, oder?
Ich sags mal so, entweder ist der Standard nicht eindeutig genug oder die Compiler-Bauer machen mal wieder was sie wollen

Edit::
Den Typ den new erwartet muss ich spätestens dann wissen, wenn ich die Standard-Library auf eine andere Plattform portiere und/oder eine Compiler unabhängige Standard-Library schreiben will (gibt sicherlich noch mehr Gründe).
-
FlashBurn schrieb:
@volkard
Aber size_t ist unterschiedlich definiert und das dürfte ja eigentlich auch nicht sein, oder?Doch, das darf sein. Es ist absolut ok. In der Praxis gibt es keine Probleme damit. Es gibt nur Probleme, wenn man erwartet, daß size_t genau 4 Bytes hat und dann beim Compilerwechsel überrascht ist.
Und natürlich, wenn man den ganzen Videofilm mit 3.7GB in einen std::vector stopfen will, was bei sizeof(size_t)==4 nicht klappen wird.
-
FlashBurn schrieb:
Ich sags mal so, entweder ist der Standard nicht eindeutig genug oder die Compiler-Bauer machen mal wieder was sie wollen

It's not a bug. It's a feature.
Der C++-Standard läßt ganz viele Sachen offen. Und allermeistens sogar mit voller Absicht.
-
FlashBurn schrieb:
Aber size_t ist unterschiedlich definiert und das dürfte ja eigentlich auch nicht sein, oder?
Ich sags mal so, entweder ist der Standard nicht eindeutig genug oder die Compiler-Bauer machen mal wieder was sie wollen

Nicht die Compiler-Bauer, sondern die CPU-Bauer
size_t ist so definiert, daß er auf deiner Zielplattform jede plausible Größenangabe aufnehmen kann, die das System hergibt.Den Typ den new erwartet muss ich spätestens dann wissen, wenn ich die Standard-Library auf eine andere Plattform portiere und/oder eine Compiler unabhängige Standard-Library schreiben will (gibt sicherlich noch mehr Gründe).
Auf Quellcode-Ebene kannst du eine ANSI-konforme Library überall hinportieren, wo du einen vernünftigen C++ Compiler zur Verfügung hast. Auf Binär-Ebene hast du vermutlich ganz andere Probleme, weil Plattform 1 womöglich nichts mit dem Maschinencode anfangen kann, den du für Plattform 2 erzeugt hast.
Und welchen Typ new erwartet, ist im Standard genau festgelegt - es ist *trommelwirbel* size_t
-
volkard schrieb:
In der Praxis gibt es keine Probleme damit.
Nur wenn ich das weiß und size_t entsprechend mit ifdef´s für den jeweiligen Compiler definiere.
Als Bsp. sei mal ein Kernel genannt, ich werde bei einem Kernel nicht die Standard-Library vom Compiler nehmen (kann ich ohnehin nicht, jedenfalls nicht so einfach), sondern entweder meine eigene schreiben oder nur das schreiben, was ich brauche (oder halt entsprechend anpassen).
Sicherlich bindet man sich gerade mit nem Kernel doch sehr stark an den Compiler, aber wenn du ihn wechselst und mit einmal feststellen musst, das der Kernel nicht mehr läuft oder kompiliert werden kann, weil die Typen nicht eindeutig definiert sind, sehe ich das als failure-by-design an.
Anderes Bsp. wären Mikrokontroller. Ich will dort auch new nutzen (als Bsp.) und dort nehme ich bestimmt keine Standard-Library sondern, werde eigenen Code nutzen und muss wieder aufpassen was der Compiler nun erwartet.
Das sind Probleme die man vllt nicht auf der PC-Plattform hat, aber wenn man mal über den Tellerrand guckt, wird man feststellen, dass es einige solcher Probleme gibt und eigentlich wurden C und C++ doch genau damit angepriesen das sie Plattform/Hardware unabhängig seien.
-
Hab ich doch mit
typedef decltype(sizeof(0)) Size;längst gelöst. Sogar zufällig ohne #ifdef. Und rede nicht vom Tellerrand.
-
Wenn du für einen Microcontroller programmierst, sollte dein Compiler schon eine portierte Standardlibrary anbieten. Und bei der Betriebssystemprogrammierung kannst du durchaus die Standardbibliothek verwenden. Bestimmte Dinge wie Speicherverwaltung usw. musst du zwar selbst implementieren (die Standardlibraryentwickler können ja nicht wissen, wie du das gerne hättest), aber es geht.
Ich sehe auch dein Problem nicht. Systeme sind unterschiedlich und erfordern unterschiedlichen Code. Das man trotzdem mit C++ platformunabhängig programmieren kann, liegt daran, weil die Bibliotheken, allen voran die Standardbibliothek, für die verschiedenen Systeme portiert sind und systemabhängige Funktionen unter einem einheitlichen Interface kapseln.
Bei Java muss eben für jedes System die JVM portiert werden, bei C++ die Standardbibliothek. Das hat nichts mit Failure-by-Design zu tun.
-
volkard schrieb:
Hab ich doch mit ...
Das muss ich irgendwie überlesen haben

Kannst du mir mal erklären was das genau bedeutet bzw. was da genau passiert? Vorallem wie daraus dann sowas wie "unsigned int" oder "unsigned long" wird.
-
FlashBurn schrieb:
volkard schrieb:
Hab ich doch mit ...
Das muss ich irgendwie überlesen haben

Kannst du mir mal erklären was das genau bedeutet bzw. was da genau passiert? Vorallem wie daraus dann sowas wie "unsigned int" oder "unsigned long" wird.
decltype ist neu. evtl hat Dein Compiler typeof oder __typeof__ oder so. Aber bald haben alle decltype.
decltype liefert den Typ eines Ausdrucks.
decltype(4) ergibt int.decltype(4) i;wird compiliert als
int i;und sizeof(egal was) liefert einen size_t.
Habe deswegen sizeof(0) genommen, weil die 0 so unauffällig ist.
sizeof(new double(3.14)) würde mich beim Drüberlesen immer stolpern lassen.
decltype(sizeof(0)) ergibt unsigned int oder unsigned long oder wasauchimmer auf dem Compiler gerade size_t ist.typedef decltype(sizeof(0)) Size;ist also automatisch das passende aus
typedef unsigned int Size;typedef unsigned long Size;typedef unsigned long long Size;typedef unsigned __int64__ Size;usw.
-
Dann muss ich noch die Frage stellen, wie war size_t vorher (bevor man decltype hatte) definiert?
-
FlashBurn schrieb:
Dann muss ich noch die Frage stellen, wie war size_t vorher (bevor man decltype hatte) definiert?
Na, der Compilerbauer hat eine <size_t.h> oder so mitgeliefert, die genau auf diesen Compiler zugeschnitten war. Spätestens die <cstring> definiert size_t. Direkt oder indem sie eine nicht vom Standard geforderte <size_t.h> oder so inkludiert.
Der Standard verlangt nur, daß der Compilerbauer Dir einen size_t zur Verfügung stellt, er muß es nicht per declytype machen, und macht es auch nicht so, sondern mit #ifdef. Den Trick habe ich außer bei mir noch nie gesehen.
Beim Kernelbauen inkludierte man halt einen header, der size_t anbietet.
-
FlashBurn schrieb:
Dann muss ich noch die Frage stellen, wie war size_t vorher (bevor man decltype hatte) definiert?
Indem in einem von Compiler bereitgestellten Headerfile (stddef.h)
typedef PassenderTyp size_t;steht.
-
Also habe das mit "decltype" gerade unter gcc 4.6.0 ausprobiert und es funktioniert nicht

Da ich unabhängig vom Compiler arbeiten möchte, nutze ich natürlich auch keine vom Compiler bereitgestellten Header-Dateien. Von daher muss ich size_t irgendwie selbst definieren.
Habe mir auch mal versucht die Definitionen von size_t in verschiedenen Standard-Libraries (vorallem C) anzugucken und die machen das auch über einige ifdef´s

So wie ich es sehe, müsste size_t genau im Standard definiert sein und nicht vom Compiler festgelegt werden.
Ich arbeite momentan in einer komplett unabhängigen Umgebung, sprich man braucht (theoretisch) nur nen Standard-konformen C/C++ Compiler und den Rest bringt meine Umgebung mit (auch die Header-Dateien und eventuell benötigte Library-Funktionen).