64Bit Ganzzahl Konstanten deklarieren
-
Hallo,
eine für ein C++ Programmierer sicher einfache Frage:
Warum funktioniert folgende Deklaration nicht? Bzw. wie deklariert man 64Bit Konstanten richtig? Wenn ich LL anhängen meckert der Compiler (VC++2005) zwar nicht, macht es aber trotzdem genauso falsch wie mit nur einen L, l oder ll.typedef LARGE_INTEGER TI64Bit; #define A0 0x0000000000000000L #define A1 0x0000000000000100L #define A2 0x0000000000000200L #define A3 0x0000000000000300L #define X0 0x0000000000010000L #define X1 0x0000000000010100L #define X2 0x0000000000010200L #define X3 0x0000000000010300L #define X4 0x0000000000010400L #define X5 0x0000000000010500L #define X6 0x0000000000010600L #define X7 0x0000000000010700L #define X8 0x0000000000010800L #define X9 0x0000000000010900L #define X10 0x0000000000010a00L #define X11 0x0000000000010b00L TI64Bit Inputs[16] = { A0, A1, A2, A3, X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11 };
Oder liegt es am Datentyp LARGE_INTEGER?
// aus winnt.h typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; }; struct { DWORD LowPart; LONG HighPart; } u; #endif //MIDL_PASS LONGLONG QuadPart; } LARGE_INTEGER;
LG Bernd
-
naja ich habe leider keine ahnung woran es nun liegen könnte aber:
warum benutzt duLARGE_INTEGER -> long long ?
soweit ich weiß geht long long auch und ist keine windows deklaration...
kann sein dass es damit nichts zu tun hat...
Gruß Chris
-
LARGE_INTEGER benutze ich, weil es ein 32Bit Programm ist und ich Zugriff auf LowPart und HighPart brauche. Daran liegt es aber nicht. Hatte long long bereits für die Inputs-Deklaration getestet. Hatte keinen Einfluss auf das Ergebniss.
-
Der Typ "long long" gehört nicht zur ISO Norm. Erst ISO C 99 hat diesen Datentypen definiert. Ob Dein C++ Compiler diesen Datentyp unterstützt, müßte in der Doku zum Compiler dokumentiert sein. In C muß man "ll" bzw. "LL" anhängen.
-
BerndD schrieb:
Bzw. wie deklariert man 64Bit Konstanten richtig?
Indem du Konstanten definierst und keine Makros. Dann ist die Auseinandersetzung mit Suffixen (an dieser Stelle) völlig unnötig.
-
Es gibt doch _Longlong im TR1, wenn der Compiler kein long long kann. Ansonsten gibt es im TR1 auch cstdint mit std::uint64_t/std::int64_t. Im Zweifelsfall, wenn man einen Compiler nutzt, der noch keinen vollen TR1-Support hat, gibt es boost/cstdint.hpp oder die boost TR1-Header.
-
camper schrieb:
BerndD schrieb:
Bzw. wie deklariert man 64Bit Konstanten richtig?
Indem du Konstanten definierst und keine Makros. Dann ist die Auseinandersetzung mit Suffixen (an dieser Stelle) völlig unnötig.
Makros sind doch reine Textersetzungen bevor (!) der Compiler den Quelltext zu sehen bekommt. Ich habe es trotzdem mit Konstanten direkt im Quelltext versucht - war ohne Auswirkung auf das Ergebnis.
rüdiger schrieb:
Es gibt doch _Longlong im TR1, wenn der Compiler kein long long kann. Ansonsten gibt es im TR1 auch cstdint mit std::uint64_t/std::int64_t. Im Zweifelsfall, wenn man einen Compiler nutzt, der noch keinen vollen TR1-Support hat, gibt es boost/cstdint.hpp oder die boost TR1-Header.
TR1 sagt mir nichts. Aber ich bin mir nun sicher, dass der von mir verwendete Compiler, Microsoft Visual C++ 2005 Version 8.0 50727.42 (RTM.050727-4200), fehlerhaft arbeitet. So ein Fehler kann man weder durch andere Datentypen noch durch irgendwelche Bibliotheken nachbessern.
Ich bin der Meinung der Compiler müsste den Suffix "LL" entweder ablehnen oder richtig verarbeiten. In meinen Fall also mindestens eine Warnung ausbringen, das er 64Bit auf 32Bit zuweist.
Ich hatte den Fehler erstmal bei mir gesucht, das der Compiler fehlerhaft arbeitet ist ja erstmal nicht anzunehmen. Die Lösung ist nun einfach, ich initialisiere die Struktur über die 32Bit Member:
typedef LARGE_INTEGER TI64Bit; #define A0 0x0000000000000000LL #define A1 0x0000000000000100LL #define A2 0x0000000000000200LL #define A3 0x0000000000000300LL #define X0 0x0000000000010000LL #define X1 0x0000000000010100LL #define X2 0x0000000000010200LL #define X3 0x0000000000010300LL #define X4 0x0000000000010400LL #define X5 0x0000000000010500LL #define X6 0x0000000000010600LL #define X7 0x0000000000010700LL #define X8 0x0000000000010800LL #define X9 0x0000000000010900LL #define X10 0x0000000000010a00LL #define X11 0x0000000000010b00LL TI64Bit Inputs[16] = { {A0,0}, {A1,0}, {A2,0}, {A3,0}, {X0,0}, {X1,0}, {X2,0}, {X3,0}, {X4,0}, {X5,0}, {X6,0}, {X7,0}, {X8,0}, {X9,0}, {X10,0}, {X11,0} };
Vielen Dank für eure Mithilfe
Bernd
-
LARGE_INTEGER ist doch nen union ....
typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; }; struct { DWORD LowPart; LONG HighPart; } u; LONGLONG QuadPart; } LARGE_INTEGER typedef union _ULARGE_INTEGER { struct { DWORD LowPart; DWORD HighPart; }; struct { DWORD LowPart; DWORD HighPart; } u; ULONGLONG QuadPart; } ULARGE_INTEGER
ne zuweissung oder initialisierung mit nem 64bit wert muss also schiefgehen, durch die typpruefung.
Klar kann man es reinterpreten, da die struct eigentlich nur genau 64 bit belegt und die auch als longlong ablegt.Ich wuerds aber andersrum machen, richtige 64bitter verwenden, weil die lassen sich direkt initialisieren, und dann einfach als ULARGE_INTEGER interpretieren, um zugriff auf low und highpart zu bekommen
ULONGLONG Inputs[16] = { 0x0000000000000000LL, 0x0000000000000001LL, ... }; ULARGE_INTEGER * pData = reinterpret_cast<ULARGE_INTEGER *>(Inputs); pData[2].LowPart = 1234;
Und mit inbuild 64 bit Datentypen funktionieren dann auch die constanten mit zuweisung ... und makros dafuer sind pfui pfui pfui ...
Ciao ...
-
RHBaum schrieb:
ne zuweissung oder initialisierung mit nem 64bit wert muss also schiefgehen, durch die typpruefung.
Klar kann man es reinterpreten, da die struct eigentlich nur genau 64 bit belegt und die auch als longlong ablegt.Die Zuweisung geht nicht schief. Ich habe dein Post zum Anlass genommen, alles nochmal durch zu probieren und da ist mir mein Irrtum aufgefallen. Es ist doch kein Compiler Fehler! War ja irgendwie klar - Gut das die M$ Programmierer hier nicht mitlesen, hätte sie mit meiner Behauptung sicher beleidigt/empört. Daher schnell meine Richtigstellung:
Es ist eins der vielen C++ Syntax Fallen in die man reintappen kann: Da man den Speicherplatz innerhalb einer Struktur/Union nicht benennen darf (wie es z.B. in Delphi sogar erforderlich ist), kann man bei einer Union nur den ersten "Zweig" befüllen, Auf u und QuadPart hat man bei der Initialisierung also keinen Zugriff. Zum Glück passen alle meine Konstanten in 32Bit, so dass meine obige Lösung für mich bestens funktioniert. Ansonsten hätte ich auch noch die in 32Bit zerhakten Werte deklarieren müssen.
Bei meinen Ausgangsbeispiel nimmt der Compiler nur den unteren 32Bit Teil meiner Konstanten und packt sie abwechselnd nach LowPart und HighPart. Da es zulässig ist, durch weglassen von Werten eine Struktur, Union oder ein Array unvollständig zu befüllen, fällt es beim Compilieren nicht auf, dass nur die Hälfte des Speichers initialisiert wird.
RHBaum schrieb:
Und mit inbuild 64 bit Datentypen funktionieren dann auch die constanten mit zuweisung ... und makros dafuer sind pfui pfui pfui ...
Nicht so pfui wie reinterpret_cast was wirklich nur in extremen Ausnahmefällen verwenden werden soll. Da ich meine Konstanten bewusst ins Code-Segment bringen will, sind Makros sicher das einzige Mittel um das erreichen zu können. Das ich mit den Konstanten auch das Array im Datensegment befüllle, ist nur wegen der Konsistenz, bei Änderung der Konstanten soll ein Änderung am Quelltext genügen.
LG
Bernd