32bit/64bit/...?
-
Badestrand schrieb:
template<int PointerBytes> struct MainTypes; template<> struct MainTypes<4> { typedef int Signed; typedef unsigned int Unsigned; }; template<> struct MainTypes<8> { typedef long long Signed; typedef unsigned long long Unsigned; }; typedef MainTypes<sizeof(void*)>::Signed ptrdiff_t; typedef MainTypes<sizeof(void*)>::Unsigned size_t;Woher weißt Du denn, dass ein
int4 Bytes groß ist undlong long8 Bytes groß ist? Wennintundcharundvoid*alle 32 Bit besitzen, bekommst Du mit sizeof jeweils eine 1 heraus.Siehe stdint.h für vorgefertigts
typedefs.Wenn man sich
typedefs fürintptr_tunduintptr_tselber basteln will, könnte man das mit TMP (template meta programming) machen. Man schreibe sich Typlisten fürsignedundunsignedGanzzahlen und durchläuft diese bis man einen gefunden hat, der die gleiche Größe wie einvoid*besitzt:struct nil {}; template<typename Head, typename Tail> struct tl { typedef Head head; typedef Tail tail; }; typedef tl<signed char, tl<short, tl<int, tl<long, tl<long long, nil> > > > > signed_integers; typedef tl<unsigned char, tl<unsigned short, tl<unsigned, tl<unsigned long, tl<unsigned long long, nil> > > > > unsigned_integers; template<typename List, unsigned Size> struct select_first_by_size; // Implementierung bleibt dem Leser als Übung ueberlassen typedef select_first_by_size< signed_integers, sizeof(void*) >::type my_intptr_t; typedef select_first_by_size< unsigned_integers, sizeof(void*) >::type my_intptr_t;Gruß,
SP
-
Sebastian Pizer schrieb:
Woher weißt Du denn, dass ein
int4 Bytes groß ist undlong long8 Bytes groß ist?Sehr wahrscheinlich weil er davon ausgeht, dass ein "normaler" Compiler genutzt wird. GCC, Builder, MSVC, Comeau ...
Sebastian Pizer schrieb:
Wenn
intundcharundvoid*alle 32 Bit besitzen, bekommst Du mit sizeof jeweils eine 1 heraus.Nur könnte dann deine spezielle Maschine keine Bytes verarbeiten. Das wäre ein ziemlicher Sonderfall

Sebastian Pizer schrieb:
Siehe stdint.h für vorgefertigts
typedefs.Witzbold. Das ist ein C99 Header und somit nicht Standard C++. Oben bemängelst du, dass die Lösung nicht dem Standard entspricht und dann verstösst du gleich selber dagegen ... lol
Sebastian Pizer schrieb:
Wenn man sich
typedefs fürintptr_tunduintptr_tselber basteln will, könnte man das mit TMP (template meta programming) machen. Man schreibe sich Typlisten fürsignedundunsignedGanzzahlen und durchläuft diese bis man einen gefunden hat, der die gleiche Größe wie einvoid*besitzt:Und in diesem Code gleich nochmals.
long longist nicht enthalten im aktuellen C++ Standard
Naja, aber man könnte auch gleich Boost verwenden:
http://www.boost.org/doc/libs/1_39_0/libs/integer/index.htmlAllerdings nützt das reichlich wenig, wenn du, wie du es vorhin angesprochen hast, nicht auf den Wert eines
sizeof(void*)Ausdruck gehen kannst.Grüssli
-
Badestrand schrieb:
unskilled schrieb:
oder wie würdet ihr euch so etwas basteln, wenn ihr es selbst machen müsstet?
Ich würde glaubich über
sizeof(long)gehen. Müsste man nochmal nachschauen, aber afair ist das sowohl im MSVC als auch unter'm g++ 32/64 Bit breit, eben je nach Konfiguration.Nein. long, sowie auch int bleiben unter 64Bit Windows 32 Bit.
http://msdn.microsoft.com/de-de/library/bb978906.aspx#_32-Bit und 64-Bit in KoexistenzLediglich Zeiger, sowie LongLong sind 64, was ich auch sinnvoll finde, dass nicht alles gleich 64 Bit wird..
-
drakon schrieb:
Lediglich Zeiger, sowie LongLong sind 64, was ich auch sinnvoll finde, dass nicht alles gleich 64 Bit wird..
Wurde bloss aus Kompatibilitätsgründen so gemacht.
"Richtiger" wäre IMO wenn zumindest long 64 Bit hätte.Und dann gleich noch "long long" mit 128 Bit, jau, was wäre das fein

-
hustbaer schrieb:
drakon schrieb:
Lediglich Zeiger, sowie LongLong sind 64, was ich auch sinnvoll finde, dass nicht alles gleich 64 Bit wird..
Wurde bloss aus Kompatibilitätsgründen so gemacht.
"Richtiger" wäre IMO wenn zumindest long 64 Bit hätte.Und dann gleich noch "long long" mit 128 Bit, jau, was wäre das fein

Ich finde je schon das komisch zu lesen: DWORD64
128 Bit, das wäre natürlich was.. :p - Ich bezweifle aber nicht, dass das früher, oder später noch kommt. Spätestens bei Windows 128Bit :p
-
DWORD64 is wirklich einer der grossen Geniestreiche von Mirkosoft

Was kommt als nächstes, BYTE24? BOOL16? FLOAT80? DOUBLE32?
Oder gleich WCHAR8
-
hustbaer schrieb:
DWORD64 is wirklich einer der grossen Geniestreiche von Mirkosoft

Was kommt als nächstes, BYTE24? BOOL16? FLOAT80? DOUBLE32?
Oder gleich WCHAR8

naja - klar ists nich ganz sauber - aber immerhin logisch ^^
man hätte auch QWORD für quad wählen können oder DDWORD xD
aber da ist DWORD64 scho ein klein wenig besser, meinst du nicht auch?!
bb
-
DDWORD
Ich bin ja kein Franzose

Hätte das ganz klar QWORD genannt!Oder es einfach mit UINT64 gut sein lassen.
-
Dravere schrieb:
Sebastian Pizer schrieb:
Woher weißt Du denn, dass ein
int4 Bytes groß ist undlong long8 Bytes groß ist?Sehr wahrscheinlich weil er davon ausgeht, dass ein "normaler" Compiler genutzt wird. GCC, Builder, MSVC, Comeau ...
Wie auch immer ... man sollte sich nicht auf die Größen verlassen. Ich würde sagen
long longist Quasi-Standard. Ohnelong longhast Du eventuell keine Ganzzahl, die groß genug für einen Zeiger ist. All das, was ich vorgeschlagen habe, würde im schlimmsten Fall einfach nicht kompilieren. Falls es kompiliert, produziert das Programm wenigstens keinen Müll (keine "silent errors").Dravere schrieb:
Sebastian Pizer schrieb:
Wenn
intundcharundvoid*alle 32 Bit besitzen, bekommst Du mit sizeof jeweils eine 1 heraus.Nur könnte dann deine spezielle Maschine keine Bytes verarbeiten. Das wäre ein ziemlicher Sonderfall

Ein Rechner kann immer Bytes einzeln verarbeiten. Nur manchmal sind Bytes auch 16 oder 32 bit groß. Es hat keiner behauptet, dass es sich dabei um Octets handeln muss.
Dravere schrieb:
Sebastian Pizer schrieb:
Siehe stdint.h für vorgefertigts
typedefs.Witzbold. Das ist ein C99 Header und somit nicht Standard C++. Oben bemängelst du, dass die Lösung nicht dem Standard entspricht und dann verstösst du gleich selber dagegen ... lol
Das war echt kein Scherz. Ich würde den Header als Quasi-Standard bezeichnen. Er wird auch in C++0x übernommen (mit einer zsätzlichen C++ Version namens
<cstdint>). Falls es einen sochen Header nicht geben sollte, kompiliert Dein Programm nicht. Falls sizeof(int)!=4 gilt, obwohl Du Dich darauf verläßt, hast Du einen "stillen Fehler". (kompiliert, aber Programm produziert Müll).Dravere schrieb:
Sebastian Pizer schrieb:
Wenn man sich
typedefs fürintptr_tunduintptr_tselber basteln will, könnte man das mit TMP (template meta programming) machen. Man schreibe sich Typlisten fürsignedundunsignedGanzzahlen und durchläuft diese bis man einen gefunden hat, der die gleiche Größe wie einvoid*besitzt:Und in diesem Code gleich nochmals.
long longist nicht enthalten im aktuellen C++ Standard
Ich bin mir dessen bewusst. Dankeschön.
Dravere schrieb:
Naja, aber man könnte auch gleich Boost verwenden:
http://www.boost.org/doc/libs/1_39_0/libs/integer/index.htmlKann man. Der Header bindet stdint.h (oder etwas vergleichbares) ein, sofern existent, und kümmert sich auch um die Fälle, in denen keine Implementierungsdetails in Headern verfügbar sind.
Dravere schrieb:
Allerdings nützt das reichlich wenig, wenn du, wie du es vorhin angesprochen hast, nicht auf den Wert eines
sizeof(void*)Ausdruck gehen kannst.Wie bitte? Du brauchst doch nur auf Gleichheit der Größen überprüfen
(sizeof(element_aus_typ_liste)==sizeof(void*)).Gruß,
SP
-
@Sebastian Pizer,
Also du darfst mit quasi Standard argumentieren, ich allerdings nicht? Interessant ...Sebastian Pizer schrieb:
Dravere schrieb:
Allerdings nützt das reichlich wenig, wenn du, wie du es vorhin angesprochen hast, nicht auf den Wert eines
sizeof(void*)Ausdruck gehen kannst.Wie bitte? Du brauchst doch nur auf Gleichheit der Größen überprüfen
(sizeof(element_aus_typ_liste)==sizeof(void*)).Das bringt dir allerdings nichts. Ich habe gerade nochmal im Standard gesucht und bin nicht fündig geworden. Vielleicht kannst du etwas dazu finden und mich korrigieren, aber mir ist nicht bekannt, dass
sizeof(void*)eine Grösse zurückliefern muss, welche einemsizeof(X)entsprechen muss, wobei X ein fundamentaler Typ ist. Alsosizeof(void*)dürfte theoretisch einen Wert von 16 zurückgegeben, während dein grösster fundamentaler Typ nur 8 ist.Grüssli
-
Dravere schrieb:
@Sebastian Pizer,
Also du darfst mit quasi Standard argumentieren, ich allerdings nicht?
Interessant ...Ja, darf ich.

Im Ernst: Der Unterschied ligt in der Kompilierbarkeit. Wenn esstdint.hnicht gibt, dann bekommst Du das Programm gar nicht erst erzeugt. Eine Annahme wie sizeof(int)==4 ist dem Compiler scheissegal. Wenn man Implementierungs-spezifische Details ausnutzt, dann sollte man dafür sorgen, dass das Programm wenigstens nicht kompiliert, wenn die Annahmen falsch sind. Außerdem iststdint.hundlong longseit 10 Jahren bei C99 dabei und ist schon seit einer ganzen Weile im C++0x Entwurf enthalten. Aktuelle Compiler, die beides können (C und C++), sollten diesen Header undlong longanbieten. Ich habe aber ehrlich gesagt nicht den Überblick über Compiler, wie es mit der Unterstützung genau aussieht. Diese Typlisten-Trickserei hätte ich wahrscheinlich mit#ifdefs geklammert, dasslong longnur dann auftaucht, wenn der Compiler das auch kann.Dravere schrieb:
Sebastian Pizer schrieb:
Wie bitte? Du brauchst doch nur auf Gleichheit der Größen überprüfen
(sizeof(element_aus_typ_liste)==sizeof(void*)).Das bringt dir allerdings nichts. Ich habe gerade nochmal im Standard gesucht und bin nicht fündig geworden. Vielleicht kannst du etwas dazu finden und mich korrigieren, aber mir ist nicht bekannt, dass
sizeof(void*)eine Grösse zurückliefern muss, welche einemsizeof(X)entsprechen muss, wobei X ein fundamentaler Typ ist.Ist
void*ein fundamentaler Typ?
Du meinst X = Ganzzahltyp.Dravere schrieb:
Also
sizeof(void*)dürfte theoretisch einen Wert von 16 zurückgegeben, während dein grösster fundamentaler Typ nur 8 ist.Kann gut sein. In einem solchen Fall gäbe es zu dem Problem auch keine Lösung. Da kann ich aber nichts für, wenn die Voraussetzungen für eine existierende Lösung nicht gegeben sind. C99 sagt auch, dass die typedefs für uintptr_t und intptr_t optional sind. Ich habe schon von Rechnern gehört, bei denen Zeiger 48 bittig waren und alle anderen Ganzzahltypen höchstens 32 Bit besaßen.
Gruß,
SP
-
Sebastian Pizer schrieb:
Ja, darf ich.

Im Ernst: Der Unterschied ligt in der Kompilierbarkeit.Nicht wirklich:
template<bool> struct StaticAssert; template<> struct StaticAssert<true> { }; // ... StaticAssert<sizeof(int) == 4> assert;Finito, hier hast du deinen gewünschten Kompilerfehler.
Sebastian Pizer schrieb:
Ist
void*ein fundamentaler Typ?
Du meinst X = Ganzzahltyp.Nein und Nein.
void*ist ein Compound Type. Das sind alle Zeiger.
X darf auch einfloatoderdoublesein, auch wenn es nicht all zu viel Sinn macht.Sebastian Pizer schrieb:
Kann gut sein. In einem solchen Fall gäbe es zu dem Problem auch keine Lösung. Da kann ich aber nichts für, wenn die Voraussetzungen für eine existierende Lösung nicht gegeben sind.
Dagegen sage ich ja auch nichts. Ich sage nur, dass du an der Lösung von Badestrand kritisierst, dass sich diese nicht an den Standard hält, aber deine tut es genauso wenig.
Grüssli
-
Dravere schrieb:
Dagegen sage ich ja auch nichts. Ich sage nur, dass du an der Lösung von Badestrand kritisierst, dass sich diese nicht an den Standard hält, aber deine tut es genauso wenig.
GrüssliSo, wie ich das sehe, macht der Typlisten-Ansatz zwei Annahmen weniger, welche nicht vom C++ Standard garantiert werden -- nämlich sizeof(int)==4 und sizeof(long long)==8.
Ich habe nie behauptet, dass "long long" Teil des C++ Standards ist. Die Nutzung von "long long" in diesem Fall ist ein Trade-Off. Entweder es gibt einen Kompilierfehler, weil "long long" nicht bekannt ist, oder es gibt einem Kompilierfehler, weil sizeof(T)<sizeof(void*) für alle anderen Ganzhaltypen T gilt und deswegen das Template-Metaprogramm fehlschlegt. Was ist das kleinere Übel? Ich weiss es nicht... Das wär mir aber auch ehrlichgesagt solange egal, bis das Programm woanders kompiliert werden soll. Dann kann man immernoch die Typlisten mit #ifdefs anpassen...
Gruß,
SP