Dirty C Tricks in vielen Compilern nicht möglich?

Gast #139784
Hallo,

Kann es sein das viele der dirty C Tricks in vielen Compiliern nicht
funktionieren?
Was ich konkret meine ist z.B. ein Array von Chars anzulegen und gleich
zeitig einer unsigend long Variable die gleiche Startadresse zu geben um
mir das Rumschieben zu ersparen.
Konkret meine ich die den CCS (in Verbindung mit PICs) und den IAR (in
Verbindung mit dem MSP430) Compiler.
Gast #139785
Nö. Sowas geht - notfalls mit einer union.

  union
  {
    char bla[4];
    long fusel;
  } CDU;

  CDU.fusel = 0x1234567;

  CDU.bla[0] = 0;

Allerdings geht das auch mit einem -brutalen und ganz und gar nicht
portierbaren- Pointer-Typecast:

  char bla[4];

  *((unsigned long *) bla) = 0x1234567;

Welches Byte wo landet ist implementierungsspezifisch.
Gast #139786
Ich habe dasselbe bei einem Compiler für den M16C gemacht:
Im Hauptprogramm ein char Array char Puffer[16384] erstellt, und in
einem anderem Programm (das anschließend über den Linker angefüft wird)
über extern unsigned int Puffer [8192] dasselbe Array erstellt. Das
funktioniert einwandfrei, nur wie macht man das in einem Programm ?
Eine Alternative die sicher funktioniert: Über Pointer...
Gast #139787
typedef union
{
  int valint;
  struct
  {
    char vh;
    char vl;
  } val
}_myint;

val (2 * char) und valint liefen auf der gleichen Adresse.
ob erst high-Byte oder low-Byte haengt vom Compiler und Controller ab.

Ciao, rg
Gast #139788
Hi,

liegt BigEndian oder LittleEndian echt vom Compiler ab? Ich dachte die
Architektur bestimmt dies (z.B. Intel / Motorola sind ja auch
verschieden). Denke nicht, daß ein Compiler da Bytes vertauscht. Wäre
ja höchst ineffizient.

Grüße,
André
Gast #139789
Also der "Trick" mit dem Union ist alles andere als Dirty und manchmal
sehr nützlich. So kann man das sehr schön für Datenpakete verwenden, in
denen ein Byte den Typ und die restlichen Bytes das jeweilige Datum
angeben.

typedef struct
{
   char typ;
   union
   {
      int valint;
      float valfloat;
   }
} data_t;

BigEndian und LittleEndian hängen tatsächlich von der Architektur ab.
Der Compiler mischt sich da meist nicht ein, bzw. macht es so, wie die
Architektur das definiert.

Die AVRs machen LittleEndian, ebenso die MSP430. Die meisten (alle?)
Motorola-CPUs sind BigEndian, ebenso alle Sparcs.

ciao, Stefan.
Gast #139790
AVR little-endian? Meistens, aber nicht immer:

ROM: little-endian.
Register: little-endian.
I/O lesen: little-endian.
I/O schreiben: big-endian.
Stack: big-endian.
Gast #139791
Ok, das stimmt. Ist das eigentlich irgendwo an einer Stelle
dokumentiert? Die IOs stehen bei den jeweiligen 16-Bit Registern. Was
ist mit dem Stack? Dazu habe ich nix gefunden.

ciao, Stefan.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.