Typ size_t beim Überschreiben von new
-
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).
-
volkard schrieb:
int ist immer 4 Byte.
long 4 oder 8.Das ist so einfach nur falsch!
Warum in drei Teufelnamen müssen immer wieder unfähige Programmierer so einem Mist verzapfen und ungültige Annahmen machen, die von niemanden garantiert werden! Es geht hier um C++ und das ist nicht nur auf Windows oder POSIX Systeme beschränkt! Aus diesem Grund ist es einen nur verdammt besch****, wenn hier jemand fortlaufend Falschinformationen verbreitet, und somit andere dazu verleitet diesen Mist nachzumachen. Software wird dadurch in der Portabilität eingeschränkt und läuft unter Umständen somit nicht mehr korrekt auf normierten Umgebungen, weil hier solche falschen Annahmen gemacht wurden. Muß das sein? Wohl eher nicht.
-
FlashBurn schrieb:
Ich habe also new bei einer Klasse überschrieben. Soweit so gut. Nun meckert mich gcc voll das new einen Parameter vom Typ size_t (long unsigned int) erwartet und ich habe new mit nem Parameter vom Typ "unsigned int" deklariert.
Für solche Fälle nimmt man ausschließlich size_t, dafür ist das da. Wenn Du etwas anderes verwendest ist das ein Bug.
-
FlashBurn schrieb:
Also im Endeffekt zeigt das mal wieder das weder C noch C++ wirklich plattformunabhängig sind und das es ohne den Compiler zu beachten nicht möglich ist bestimmten Code (z.B. die C++ Standard-Library) zu schreiben.
Doch das ist möglich, man muß dazu nur die vom Compiler definierten typedefs nutzen. Ich verstehe es nicht, weshalb immer wieder versucht wird statt size_t irgend etwas anderes zu verwenden.
-
FlashBurn schrieb:
Also habe das mit "decltype" gerade unter gcc 4.6.0 ausprobiert und es funktioniert nicht

Da mußt Du zur Zeit noch C++0x per Hand anmachen.
Und typeof hat er glaub ich schon viel länger.FlashBurn schrieb:
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.
Es ist keine Schande, wenn nachher sowas rauskommt.
#if defined __GCC__ typedef typeof(sizeof(0)) Size; #elif defined __MSCVER__ typedef _typeof(sizeof(0)) Size; #elif defined __THE_OTHER_CPLR__ typedef unsigned short Size; #elif defined __THE_MORE_OTHER_CPLR__ #if __MACHINE_BITS__ == 64 typedef unsigned long Size; #else typedef unsigned int Size; #endif #else #error Ups, finde mal raus, wie man's mit Deinem Compiler macht und schreib's hier rein #endifUnd das steht ja nicht ewig da. Mit C++0x ist ja versprochen, daß es decltype gibt.
-
FlashBurn schrieb:
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.
[...]
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 mitDu scheinst etwas misszuverstehen. Zu einem standardkonformen Compiler gehören die entsprechenden Header. Nur der Compiler weiß, welchen Typ
sizeofbei ihm liefert, also kann auch nur er es dir sagen. Und das macht er mit einem standardisierten Header, der den Typedefsize_tbeeinhaltet.
-
ipsec schrieb:
Zu einem standardkonformen Compiler gehören die entsprechenden Header. Nur der Compiler weiß, welchen Typ sizeof bei ihm liefert, also kann auch nur er es dir sagen. Und das macht er mit einem standardisierten Header, der den Typedef size_t beeinhaltet.
Es ist also Standard das der Compiler entscheidet wie eine Sprache zu interpretieren ist und nicht der Standard? Heißt auch, der Compiler legt also fest, wie groß die einzelnen Typen sind (das ist im Endeffekt das was du gesagt hast) und das finde ich nicht "standardisiert"

Ich sehe es halt einfach so, dass eine Sprache unabhängig vom Compiler sein sollte und nicht das jeder Compiler sein eigenes Süppchen kocht. Ein Problem sind dabei natürlich die Standardizierungsverfahren bzw. die Gruppen die das machen. Meistens (wenn nicht immer) hängen die der Realität mal weniger und mal sehr viel mehr hinterher.
Es gibt übrigens unter gcc (und unter clang dürfte es auch funktionieren) einen Parameter "-ffreestanding", der besagt, dass keine Standard-Library und damit auch keine Header-Datei zur Verfügung stehen.
Ich muss C++0x noch per Hand anmachen? Das werde ich doch gleichmal ausprobieren.
-
FlashBurn schrieb:
Es ist also Standard das der Compiler entscheidet wie eine Sprache zu interpretieren ist und nicht der Standard? Heißt auch, der Compiler legt also fest, wie groß die einzelnen Typen sind (das ist im Endeffekt das was du gesagt hast) und das finde ich nicht "standardisiert"
C++ ist eine Sprache für mehrere Platformen. Und wie du sicher leicht einsehen wirst, sollte auf einem 16bit-Embedded-System mit wenigen Megabyte RAM
size_teine andere Größe haben als auf einem Großrechner mit mehreren hundert Gigabyte RAM. Was soll also deiner Meinung nach der Standard dafür festlegen? Wenn es festgelegt werden müsste, wäre nur 64bit als Größe sinnvoll, damit kann man aber auf einem 16bit-System nur äußerst unperformant rechnen. Und sobald 128bit-Systeme rauskommen kann man nicht den ganzen Arbeitsspeicher adressieren. Das nenne ich Failure-by-Design.
Deswegen ist die Größe (und somit im Endeffekt der Typ) vonsize_tbewusst dem Compiler überlassen, der die Entscheidung wiederrum auf Basis des Zielsystems trifft.
Entsprechendes gilt für die anderen Datentypen.Hast du denn einen Anwendungsfall, der eine festgelegte Größe von
size_tnotwendig macht?
-
FlashBurn schrieb:
Ich sehe es halt einfach so, dass eine Sprache unabhängig vom Compiler sein sollte und nicht das jeder Compiler sein eigenes Süppchen kocht.
Es kocht ja auch nicht jeder C++ Compiler sein eigenes Süppchen. Der Standard definiert die Sprache. Dabei lässt er bestimmte Dinge mehr oder weniger offen, und zwar ganz absichtlich. Meist weniger offen, da meist ein Rahmen gesetzt wird. Wie eben bei den Typen (die Mindestbreite ist da ja vorgeschrieben).
Weiters sind oft Mittel vorgeschrieben über die man rausbekommen kann wie eine bestimmte Implementierung ("der Compiler") die Dinge nun sieht (INT_MIN, INT_MAX etc.).Wir sind hier also ganz weit weg davon dass ein C++ Compiler machen kann was er will.
Ein Problem sind dabei natürlich die Standardizierungsverfahren bzw. die Gruppen die das machen. Meistens (wenn nicht immer) hängen die der Realität mal weniger und mal sehr viel mehr hinterher.
Nochmal: das hat nichts damit zu tun dass das Standardkomitee diese Dinge übersehen hat, und auch nichts damit zu tun dass sie ein bestimmte Compiler nicht korrekt umsetzt. Der Standard lässt diese Freiheiten ganz bewusst.
Wenn du das nicht gut findest, OK, jeder hat ein Recht auf eine eigene Meinung. Nur bringt es rein gar nichts sich darüber zu beklagen oder zu wundern, denn der C++ Standard wird sich davon nicht ändern.
(BTW: mir persönlich wäre es auch lieber wenn der C++ Standard weniger solche Freiheiten lassen würde. Ändert aber nix.)Finde dich also damit ab, oder such dir eine andere Sprache aus. Java oder C# lassen z.B. weit weniger Freiheiten. Bzw. es gibt auch sicher non-GC non-IL Sprachen die "enger" definiert sind.
-
Naja, ich würde es vorziehen wenn man eindeutig definierte Typen hätte (z.B. uin8, int8, uint16, int16, ...) ohne das durch Testen (und ich will auch keine Header-Dateien vom Compiler, das muss Compiler unabhängig sein) herauszufinden und size_t müsste auch ein Standardtyp sein (so wie int, char, ...) und wäre dann so groß wie ein sizeof(void*).
Es ghet mir auch nicht darum das size_t eine festgelegte Größe hat (naja irgendwo schon ;)), sondern dass ich size_t Compiler unabhängig nutzen oder definieren kann.
Wenn ich jetzt nen int auf ner 32bit Architektur habe und der ist dort 4Byte groß und ich arbeite z.B. mit dem Überlauf und portiere den Code dann auf eine 64bit Architektur und dort ist int mit einmal 8Byte groß und schon funktioniert mein Code nicht mehr, weil die Typen halt nicht eindeutig definiert sind.
Was das sich damit abfinden betrifft, um es mal auf andere Sachen zu übertragen. Dann muss man sich auch mit der Politik abfinden oder in ein anderes Land auswandern

Kritik ist meiner Meinung immer angebracht, Problem hier (C++) ist halt nur das man die Kritik nur schwer an die richtigen Stellen bekommt
-
FlashBurn schrieb:
Wenn ich jetzt nen int auf ner 32bit Architektur habe und der ist dort 4Byte groß und ich arbeite z.B. mit dem Überlauf und portiere den Code dann auf eine 64bit Architektur und dort ist int mit einmal 8Byte groß und schon funktioniert mein Code nicht mehr, weil die Typen halt nicht eindeutig definiert sind.
Das Arbeiten mit dem Überlauf darfste ja auch erst machen, wenn Du Dich bewußt dazu entscheiden hast, Dich an 32-Bitter zu binden und dabei zu bleiben.
Haste die Entscheidung nicht getroffen, darfste das nicht.
Dann nimm uint32 um genau dort Überläufe zu haben.FlashBurn schrieb:
Naja, ich würde es vorziehen wenn man eindeutig definierte Typen hätte (z.B. uin8, int8, uint16, int16, ...) ohne das durch Testen (und ich will auch keine Header-Dateien vom Compiler, das muss Compiler unabhängig sein) herauszufinden und size_t müsste auch ein Standardtyp sein (so wie int, char, ...) und wäre dann so groß wie ein sizeof(void*).
Und was machste mit Funktionsüberladungen, wenn es mehrere Namen für den selben Typ gibt? Nee, das wäre zu ärgerlich. Und sollen es unterschiedliche Typen sein, wie char und signed char? Ist ja noch schlimmer.
FlashBurn schrieb:
Es ghet mir auch nicht darum das size_t eine festgelegte Größe hat (naja irgendwo schon ;)), sondern dass ich size_t Compiler unabhängig nutzen oder definieren kann.
Compilerunabhängig, oder besser zielplattformunabhängig, kann nicht gehen, weil size_t sinnvollerweise mit der Zeit wachsen kann.
-
FlashBurn schrieb:
Naja, ich würde es vorziehen wenn man eindeutig definierte Typen hätte (z.B. uin8, int8, uint16, int16, ...) ohne das durch Testen (und ich will auch keine Header-Dateien vom Compiler, das muss Compiler unabhängig sein)
Ich verstehe nicht, warum du eine Grneze zwischen Sprachstandard und der Standardbibliothek setzt? Es gibt eine Standarddatei, die jede C++ Implementierung mitbringen muss, in der ein uint32 definiert ist. Der einzige Unterschied ist, dass im Standard im einen Fall stehen würde: "Es gibt das Keyword uint32_t das exakt 32 Bit groß auf jeder Plattform ist" und in anderen: "Es gibt eine Headerdatei stdint.h in der ein Typ uint32_t definiert ist, der exakt 32 Bit groß ist". Warum sollte das eine besser als das andere sein? Und warum bist du im einen Fall Compilerunabhängig und im anderen nicht?