Typ size_t beim Überschreiben von new
-
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?
-
[quote="otze"]
FlashBurn schrieb:
Es gibt eine Standarddatei, die jede C++ Implementierung mitbringen muss, in der ein uint32 definiert ist.
Dies Datei gibt es afaik nicht im aktuellen C++-Standard, sondern erst in C++-11. Allerdings ist sie im C-Standard enthalten und daher vermutlich für die meisten Compiler auch verfügbar.
-
manni66 schrieb:
Dies Datei gibt es afaik nicht im aktuellen C++-Standard, sondern erst in C++-11. Allerdings ist sie im C-Standard enthalten und daher vermutlich für die meisten Compiler auch verfügbar.
Nicht bei MSVC bis 2008. Allerdings kann man auf Boost zurückgreifen oder sich diese Ausnahme selbst herdefinieren - so ziemlich alle anderen kontemporären Compiler kennen stdint.h.
-
volkard schrieb:
Compilerunabhängig, oder besser zielplattformunabhängig, kann nicht gehen, weil size_t sinnvollerweise mit der Zeit wachsen kann.
Deswegen wäre es ja nicht verkehrt wenn man size_t im Standard hätte (wie z.b. int, char, ...) auch schon deswegen weil es ja bei new benutzt wird, was ja zum Sprachumfang gehört.
volkard schrieb:
Dann nimm uint32 um genau dort Überläufe zu haben.
Dann müsste ich mir den aber definieren und das geht halt nicht Compiler-abhängig.
volkard schrieb:
Und was machste mit Funktionsüberladungen, wenn es mehrere Namen für den selben Typ gibt?
Deswegen wäre es doch ausreichend wenn man int8, uint8 usw. hat. Wozu brauch man denn unterschiedliche Bezeichner für ein und den selben Typ?
otze schrieb:
Warum sollte das eine besser als das andere sein? Und warum bist du im einen Fall Compilerunabhängig und im anderen nicht?
Wenn ich eine Headerdatei nutzen muss die der Compiler mitbringt, bin ich von diesem Compiler abhängig und es ist, aus meiner Sicht, auch nicht Teil der Sprache, weil alles was Teil der Sprache (und damit meine ich jetzt die Schlüsselwörter) muss der Compiler halt einfach so unterstützen. Das nächste ist, uint? und co sind nicht im Standard drin, sprich ein Standard-konformer Compiler muss auch nicht solch eine Datei mitliefern. Es kann also passieren das wenn ich den Compiler wechsel (und dieser sich ganz genau an den Standard hält) das mein Code dann nicht mehr compilierbar ist.
Im Endeffekt ist für mich auch erstmal alles was nicht im Standard ist nicht vorhanden. Ich wollte es so hinbekommen, das man einfach irgendeinen C/C++-Compiler (der natürlich den Standard einhält) nehmen kann und mein Code kann übersetzt werden und das auch ohne das eine Standard-Library portiert wurde (freestanding).
-
FlashBurn schrieb:
Ich wollte es so hinbekommen, das man einfach irgendeinen C/C++-Compiler (der natürlich den Standard einhält) nehmen kann und mein Code kann übersetzt werden und das auch ohne das eine Standard-Library portiert wurde (freestanding).
Ok. Aber wenn Du das auch so machen willst, daß jeder Compiler den Code frißt, wirst Du wahnsinnig.
Hin und wieder für die üblichsten Compiler ein #ifdef und sehr unübliche Compiler zu vertageb, ist echt die bessere Wahl.Ohne decltype oder typeof.
#include <iostream> using namespace std; char (&typeToInt(unsigned char))[1]; char (&typeToInt(unsigned short))[2]; char (&typeToInt(unsigned int))[3]; char (&typeToInt(unsigned long))[4]; char (&typeToInt(unsigned long long))[5]; template<int> struct IntToType; template<> struct IntToType<1>{typedef unsigned char type;}; template<> struct IntToType<2>{typedef unsigned short type;}; template<> struct IntToType<3>{typedef unsigned int type;}; template<> struct IntToType<4>{typedef unsigned long type;}; template<> struct IntToType<5>{typedef unsigned long long type;}; typedef typename IntToType<sizeof(typeToInt(sizeof(0)))>::type Size; void* operator new(Size); int main() { }
-
FlashBurn schrieb:
volkard schrieb:
Compilerunabhängig, oder besser zielplattformunabhängig, kann nicht gehen, weil size_t sinnvollerweise mit der Zeit wachsen kann.
Deswegen wäre es ja nicht verkehrt wenn man size_t im Standard hätte (wie z.b. int, char, ...)
site_tist im Standard. Man kann genau die Seite bennenen, wosize_tdefiniert wird. Da steht eben, dass es in einem Header definiert werden muss, den jeder Compiler mitliefern möge.Eine Designphilosopie von C++ ist es, den eigentlichen Sprachcore möglichst klein zu halten und stattdessen neue Funktionen über Standardheader zur Verfügung zu stellen.
Eigentlich müssen diese Header auch nicht physisch vorhanden sein noch müssen sie Inhalt enthalten. Wichtig ist nur: wenn diese Header per Include eingebunden werden, müssen die entsprechenden Bezeichner verfügbar sein.Um es also nochmal klarzustellen:
size_tist ein in C++ eingebauter Typ.Übrigens sind zum Beispiel
operator newundoperator deletezusammen mitnothrow,bad_allocetc. auch in Bibliotheksheadern (#include <new>) definiert. Jetzt wo du das weißt, fühlst du dich genötigt, für dein freestanding Environment diese selbst zu implementieren, weil sie ja nicht zum Standard gehören?
-
ipsec schrieb:
Um es also nochmal klarzustellen: size_t ist ein in C++ eingebauter Typ.
Da kommen wir jetzt zwar zur Haarspalterei, aber dann ist "foo" auch ein in C++ eingebauter Typ. Denn ich kann ja "typedef int foo" machen

Mir geht es darum, das einmal new(unsigned int) und einmal new(unsigned long) definiert ist und das ja eigentlich nicht sein dürfte. Denn size_t wird ja durch den entsprechenden Typ ersetzt und wird erst dann übersetzt. Besser wäre es wenn alles andere als new(size_t) einen Fehler geben würde.
ipsec schrieb:
Übrigens sind zum Beispiel operator new und operator delete zusammen mit nothrow, bad_alloc etc. auch in Bibliotheksheadern (#include <new>) definiert. Jetzt wo du das weißt, fühlst du dich genötigt, für dein freestanding Environment diese selbst zu implementieren, weil sie ja nicht zum Standard gehören?
Das wusste ich noch gar nicht, ich dachte immer new und co gehören direkt zum Sprachumfang und sind nicht irgendwie definiert. Dann wird ja auch die ganze Diskussion um size_t "sinnlos", aber nur wenn ich es auch abschalten könnte das new und co immer definiert werden, sondern das wenn ich sie nicht per Hand einbinde, dass sie dann auch nicht zur Verfügung stehen (geht das?).
Exceptions gehören z.B. auch zum Sprachstandard, aber es gibt keine Implementierungsdetails (meines Wissens nach) und dadurch kann es passieren, das man Code aus unterschiedlichen (bzw. sogar vom gleichen) Compilern nicht zusammen verwenden kann, weil die Exceptions unterschiedlich implementiert wurden. Das gleiche gilt auch für RTTI (obwohl ich mir da gerade nicht sicher bin). Das sind z.B. auch Dinge die ich selber implementieren möchte (und das aus mehreren Gründen).
-
FlashBurn schrieb:
Da kommen wir jetzt zwar zur Haarspalterei, aber dann ist "foo" auch ein in C++ eingebauter Typ. Denn ich kann ja "typedef int foo" machen

Also ich sehe einen Unterschied zwischen einem typedef in einer Datei deren Existenz der Standard für jeden Compiler garantiert und einem typedef das du dir selbst in den Code frickelst. Nebenbei verhält sich mein Compiler beim size_t typedef anders als bei anderen typedefs(er wird nicht durch seinen wahren Typen in Fehlermeldungen ersetzt). meine IDE färbt das Ding sogar ein. Offensichtlich nimmt size_t also eine Sonderrolle ein.
Ansonsten: du glaubst wirklich, dass du die Standardbibliothek besser implementieren könntest, als Leute, die den Code speziell auf eine Plattform anpassen und den ganzen Tag nichts anderes tun als dafür zu sorgen, dass das Ding schnell und bugfrei ist und den Standard mit all seinen Anforderungen so gut wie möglich erfüllt?
nebenbei: wenn du ganz konsequent sein willst, dann musst du auch auf die C-Funktionen wie malloc usw verzichten. Kernelaufrufe oder Betriebssystemaufrufe gehen dann natürlich auch nicht. Allerdings wirds dir dann völlig unmöglich sein, ne Datei zu öffnen, Text auf die Konsole auszugeben oder überhaupt Speicher anzufordern. Assembler rettet dich auch nicht, weil es wohl nichts Compilerabhängigeres gibt.