Hallo, Gibt es einen ANSI/POSIX-, Ordinal- oder GCC-spezifischen Datentyp TYPE für den auf allen Architekturen sizeof(TYPE) == sizeof(void*) gilt? Hintergrund: Bit-OPs auf Adressen in Low-Level-Code ähnlich diesem Beispiel: void *addr1; void *addr2; addr2 = (void*) (((TYPE) addr1) ^ ((TYPE) 0x0f)) ; Festzustehen scheint, dass die Antwort weder "short", noch "int" oder "long" lautet, da sich mit GCC Gegenbeispiele finden lassen [1,2]. Als heisser Kandidat erscheint mir noch ptrdiff_t (aus stddef.h), nur konnte ich auch da ein Gegenbeispiel finden, das nicht funktioniert [2]. Oder ganz anders gefragt: Gibt es einen anderen Weg zur portablen Adressarithmetik? Ralf [1] Getestet mit ca. 10 verschiedenen Cross-GCCs. [2] Es könnte sich natürlich auch um Bugs in GCC handeln.
Hi, On Wed, 22 Oct 2003, Ralf Corsepius wrote:
sizeof(TYPE) == sizeof(void*)
Ein integertyp, der pointer aufnehmen kann, und bei Zuweisung an pointern
den Pointer nicht aendert ist 'intptr_t' (und uintptr_t), ein C99 Typ, der
in
Hintergrund: Bit-OPs auf Adressen in Low-Level-Code ähnlich diesem Beispiel:
void *addr1; void *addr2; addr2 = (void*) (((TYPE) addr1) ^ ((TYPE) 0x0f)) ;
Das ist uebrigens so und so unportabel, egal welcher Typ benutzt wird. In ISO-C sind pointer nur so lange valide, solange sie in das selbe Objekt zeigen von dessen Addresse sie initialisiert wurden.
Oder ganz anders gefragt: Gibt es einen anderen Weg zur portablen Adressarithmetik?
Das da oben ist keine Addressarithmetik im Sinne von C. Was willst du denn damit erreichen, dass du die unteren 4 Bits in einer Addresse flipst? Ciao, Micha.
On Wed, 2003-10-22 at 15:20, Michael Matz wrote:
Hi,
On Wed, 22 Oct 2003, Ralf Corsepius wrote:
sizeof(TYPE) == sizeof(void*)
Ein integertyp, der pointer aufnehmen kann, und bei Zuweisung an pointern den Pointer nicht aendert ist 'intptr_t' (und uintptr_t), ein C99 Typ, der in
definiert ist. Grr, hilft mir nicht wirklich weiter, da es stdint.h und inttypes.h für die mich hier interessierenden Toolchains (gcc-3.x + newlib-1.11.0) nicht gibt.
Ein Ausweg wäre, sie zu implementieren. Nur ist das bekanntermassen
alles andere als trivial. Da die Grössen der Typen auch noch vom
Compiler und den verwendeten Compiler-Flags abhängen, sind Zweifel
angebracht, ob eine Implementierung ausserhalb des GCC sinnvoll wäre.
Frage ich mal anderes herum: Gibt es ein GCC-Predefine, das die Größe
eines Pointers beinhaltet? Dann wäre es möglich mit Hilfe einer #define
Kaskade die #defines aus
Hintergrund: Bit-OPs auf Adressen in Low-Level-Code ähnlich diesem Beispiel:
void *addr1; void *addr2; addr2 = (void*) (((TYPE) addr1) ^ ((TYPE) 0x0f)) ;
Das ist uebrigens so und so unportabel, egal welcher Typ benutzt wird. Ich weiss ;)
In ISO-C sind pointer nur so lange valide, solange sie in das selbe Objekt zeigen von dessen Addresse sie initialisiert wurden. Das tun sie im realen Code auch.
Mein eigentliches Problem geht weiter: Der bisherige Code ging von den Annahmen sizeof(int) == sizeof(void*) und von sizeof(int) == sizeof(void*) == 32bit aus (Natürlich hard-codiert und gut im Code versteckt :( ). Das funktioniert mit GCC auf einer Vielzahl von Architekturen, aber leider nicht auf allen, insbes. nicht auf manchen 16/32bit-Architekturvarianten (z.B. h8300).
Oder ganz anders gefragt: Gibt es einen anderen Weg zur portablen Adressarithmetik?
Das da oben ist keine Addressarithmetik im Sinne von C. OK, Bit-OPs auf Adressen wäre wohl richtiger gewesen.
Was willst du denn damit erreichen, dass du die unteren 4 Bits in einer Addresse flipst?
Das war ein Codeschnipsel aus einem Treiber, andere Code-Teile mit ähnlichen Konstrukten sind Teile eines Memorymanagementsystem (ink. Adressenalignment), wiederum andere Code-Teile sind schlichtweg unsauber ("opaque") programmierte Low-Level-Codeteile mit KnR-Vergangenheit. Dabei kommen im realen Code praktisch alle Bitoperationen, alle Arten von Pointern und volatile-Pointern vor, wobei wild hin und her gecastet wird. Ralf
Hi, On Wed, 22 Oct 2003, Ralf Corsepius wrote:
Frage ich mal anderes herum: Gibt es ein GCC-Predefine, das die GröÃe eines Pointers beinhaltet?
Also, vergiss dass ich dir das erzaehlt habe, aber so: typedef unsigned int PType __attribute__((mode(pointer))); kann man einen Typ names PType definieren, der ein unsigned Integertyp und genau so breit wie ein Pointer ist.
Mein eigentliches Problem geht weiter: Der bisherige Code ging von den Annahmen sizeof(int) == sizeof(void*) und von sizeof(int) == sizeof(void*) == 32bit aus (Natürlich hard-codiert und gut im Code versteckt :( ).
Mein Beileid. Selbst die Annahme sizeof(long)==sizeof(void*) waere besser gewesen, da sie auf den meisten Plattformen Tatsache zutrifft. Ciao, Micha.
participants (2)
-
Michael Matz
-
Ralf Corsepius