Forum: Compiler & IDEs C-Frage


von Carola (Gast)


Lesenswert?

Hallo C-Spezialisten,

ich habe ein Problem mit fogendem wohl nicht ganz ANSI-konformen
Programmschnipsel:

typedef union uREG08
    {
    uint8_t  byte;
    struct      {
      uint8_t _0 :1;
      uint8_t _1 :1;
      uint8_t _2 :1;
      uint8_t _3 :1;
      uint8_t _4 :1;
      uint8_t _5 :1;
      uint8_t _6 :1;
      uint8_t _7 :1;
      }bit;
    }tREG08;

Was bedeutet z.B.

uint8_t _0 :1;

wie schreibt man das ANSI konform?

Vielen Dank

Carola

von Rolf Magnus (Gast)


Lesenswert?

> ich habe ein Problem mit fogendem wohl nicht ganz ANSI-konformen
> Programmschnipsel:

Wie kommst du darauf?

> Was bedeutet z.B.
>
> uint8_t _0 :1;

Es bedeutet, daß in der Struct ein Element mit Namen _0 angelegt wird,
das nur ein einziges Bit breit is.

> wie schreibt man das ANSI konform?

Genauso.

von Carola (Gast)


Lesenswert?

@Rolf:

Vielen Dank!

ist dann bei uint8_t _0 :1

_0 eine Variable?


Carola

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Nein, die Variable legst Du mit:

tREG08 val;

an. Sie heist dann 'val'. Zugriff auf die Bestandteile diese Variable
geht dann per:

val.bit._0 = 1;

Oder eben:

uint8_t x = val.byte;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

_0 ist ein Strukturelement (member).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Der führende Unterstrich im Element-Namen ist übrigens wirklich
nicht ganz standardkonform, da führende Unterstriche für ,,die
Implementierung'' reserviert sind (sprich: für Compiler und
Bibiothek).  Ersetze die Unterstriche besser durch ein ,b' zum
Beispiel, also auf die Bits kann man dann zugreifen mit val.bit.b0.

Btw., der Standard überlässt die Bitreihenfolge der jeweiligen
Implementierung.  Der entsprechende Code ist also zwar
standardkonform, aber mitnichten portabel.

von Rolf Magnus (Gast)


Lesenswert?

> Der führende Unterstrich im Element-Namen ist übrigens wirklich
> nicht ganz standardkonform, da führende Unterstriche für ,,die
> Implementierung'' reserviert sind (sprich: für Compiler und
> Bibiothek).

Das stimmt nicht. Reserviert sind nur führende Unterstriche, auf die
ein Großbuchstabe oder ein weiterer Unterstrich folgt. Alles andere,
was mit Unterstrich anfängt, ist zwar teilweise auch reserviert, aber
auf struct-Members trifft es nicht zu.

> Btw., der Standard überlässt die Bitreihenfolge der jeweiligen
> Implementierung.  Der entsprechende Code ist also zwar
> standardkonform, aber mitnichten portabel.

Naja, "mitnichten" ist doch etwas übertrieben. Es ist zwar in der
Norm (nicht Standard) nicht festgelegt, aber kennst du eine
Implementation, auf der das anders als oben erwartet ist? Ich gebe zu,
daß es bei 16 oder mehr bits wieder anders aussieht, wegen little
endian vs. big endian.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Reserviert sind nur führende Unterstriche, auf die ein Großbuchstabe
> oder ein weiterer Unterstrich folgt. Alles andere, was mit
> Unterstrich anfängt, ist zwar teilweise auch reserviert, aber auf
> struct-Members trifft es nicht zu.

OK, hast Recht.  Allerdings sind die Regeln für den Rest so wenig
einprägsam, dass ich mir das eher nicht im Kopf behalten würde und auf
führende Unterstriche generell verzichten würde.

Erlaubt:

struct foo {
  int _bar;
};

Nicht erlaubt:

struct _foo {
  int bar;
};

Um das rauszufinden, muss ich aber wirklich erst im Standard
nachgucken.  (Klar, bei näherem Hinsehen ist eine gewisse Logik drin,
das _bar da oben kann mit nichts aus der Bibliothek kollidieren, da es
zum namespace von struct foo gehört und nur in diesem eine Bedeutung
hat.)

> Es ist zwar in der Norm (nicht Standard) nicht festgelegt, aber
> kennst du eine Implementation, auf der das anders als oben erwartet
> ist?

Hab' ich mir nie die Mühe gemacht, das anzusehen.  Da sie als
implementation defined bezeichnet werden, nehme ich sie für derartige
Zwecke einfach nicht, sondern nehme lieber gewöhnliche Bitmasken.  (An
dieser Stelle soll dem Vernehmen nach Ada einfach mal schlauer gewesen
sein.)  Bitfields sind trotzdem hin und wieder recht nett, z.B. wenn
man Platz sparen will und ein paar globale Interruptflags braucht,
denen man dann nicht jedem ein Byte spendieren möchte.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.