Forum: Mikrocontroller und Digitale Elektronik Frage zu Struct


von Mathias (Gast)


Lesenswert?

Hallo,

ich habe mir grade die Beschreibung zu Bitfeldern im Tutorial angesehen. 
Ich verstehe nur nicht warum man da kein unsigned char oder uint8_t 
nimmt.
Also was ist besser:

1.:
1
struct {
2
   unsigned bStatus_1:1; // 1 Bit für bStatus_1
3
   unsigned bStatus_2:1; // 1 Bit für bStatus_2
4
   unsigned bNochNBit:1; // Und hier noch mal ein Bit
5
   unsigned b2Bits:2;    // Dieses Feld ist 2 Bits breit
6
   // All das hat in einer einzigen Byte-Variable Platz.
7
   // die 3 verbleibenden Bits bleiben ungenutzt
8
} x;

2.:
1
struct {
2
   unsigned char bStatus_1:1; // 1 Bit für bStatus_1
3
   unsigned char bStatus_2:1; // 1 Bit für bStatus_2
4
   unsigned char bNochNBit:1; // Und hier noch mal ein Bit
5
   unsigned char b2Bits:2;    // Dieses Feld ist 2 Bits breit
6
   // All das hat in einer einzigen Byte-Variable Platz.
7
   // die 3 verbleibenden Bits bleiben ungenutzt
8
} x;

Oder 3.:
1
struct {
2
   uint8_t bStatus_1:1; // 1 Bit für bStatus_1
3
   uint8_t bStatus_2:1; // 1 Bit für bStatus_2
4
   uint8_t bNochNBit:1; // Und hier noch mal ein Bit
5
   uint8_t b2Bits:2;    // Dieses Feld ist 2 Bits breit
6
   // All das hat in einer einzigen Byte-Variable Platz.
7
   // die 3 verbleibenden Bits bleiben ungenutzt
8
} x;

Klärt mich doch mal bitte auf.


Mathias

von Karl H. (kbuchegg)


Lesenswert?

Weil es völlig wurscht ist.

Laut C-Standard muss an dieser Stelle entweder ein signed int oder ein 
unsigned int stehen. Wobei das int im Grunde Nebensache ist. Es geht nur 
um die Spezifikation ob ein Bithaufen ein Vorzeichen haben soll oder 
nicht. Aber abgesehen davon ordnet sich der Compiler die Bits selber an 
und benutzt soviele Bytes wie er dazu braucht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wirf alle drei Varianten nacheinander in Deinen Compiler und lass Dir 
mal ein sizeof davon ausgeben.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

... und einem einzelnen Bit ist das Vorzeichen schnuppe. Wo soll es auc 
hin ?

von max (Gast)


Lesenswert?

Joachim Drechsel schrieb:
> ... und einem einzelnen Bit ist das Vorzeichen schnuppe. Wo soll es auc
> hin ?

Erm? Seit wann braucht im 2er Komplement das Signum ein zusätzliches 
Bit?

0b0 -> 0
0b1 -> -1

Schnuppe ist es nicht. Multipliziere mal mit einem größerem Ordinal.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

max schrieb:
> 0b0 -> 0
> 0b1 -> -1

Der ist gut :-)))

von max (Gast)


Lesenswert?

1
typedef struct AB
2
{
3
  signed a:1;
4
  signed b:1;
5
} AB ;
6
7
int _tmain(int argc, _TCHAR* argv[])
8
{
9
10
  AB test ;
11
  test.a = 0x0 ;
12
  test.b = 0x1 ;
13
14
  printf("a: %d, b: %d", test.a, test.b) ;
15
16
17
  return 0;
18
}

Ergebnis:
a: 0, b: -1

Probiers selber aus!

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

printf() kann keine Binärwerte als Bits ausgeben ...

Du verwendest da %d (int it Vorzeichen) :-)))

von max (Gast)


Lesenswert?

Was ist denn das für eine Argumentation? Wenn wenn ich ein unsigned 
forcieren würde, dann natürlich würde dort unsigned ausgegeben werden.

Aber: a und b sind signed. Sie werden in der impliziten Typwandlung bei 
der Parameterübergabe auf die nötoige Bitbreite erweitert und das 
Vorzeichen mitgenommen. Würde das nicht geschehen, würde 0b00...00 und 
0b00...01 übergeben werden, was auch als signed interpretiert 0 und +1 
ist.

Das jedoch widerspricht der Ausgabe.

Du kannst gerne auch kreuz und quer damit rechnen. Addier es auch ein 
unsigned char oder was immer du willst. ohne expliziten Cast ist die 
Interpretation signed und somit wie von mir dargestellt.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Sorry, aber ich halte es für so richtig unsinnig, einem einzelnen
Bit ein Vorzeichen unterzuschieben.

von Karl H. (kbuchegg)


Lesenswert?

@Joachim

Das mag schon sein, dass man das für unsinnig hält. Wie oft braucht man 
denn wirklich eine Variable die entweder 0 oder -1 sein kann?

Es ist jedoch einfach nur konsequent durchgezogen und ergibt sich ganz 
von alleine in der Form. Und in einem gewissen Sinne bin ich froh, dass 
es da keine Ausnahmeregelung gibt. Wenn man einer Abfolge von n Bits ein 
Vorzeichen verpassen kann, dann muss das auch für n gleich 1 gelten 
können. Und das tuts ja auch. In völliger Analogie (und mit allen 
Konsequenzen wie zb mgl. Zahlenbereich) zum Fall n>1.

Ausnahmen in einer Programmiersprache sind immer schlecht.

von Christian G. (christian_g83)


Lesenswert?

Joachim Drechsel schrieb:

> Sorry, aber ich halte es für so richtig unsinnig, einem einzelnen
> Bit ein Vorzeichen unterzuschieben.

Was soll daran unsinniger sein als zwei, drei oder acht Bits ein 
Vorzeichen unterzuschieben?

Anstatt der beiden Zustände 0 und 1 hat man dann eben die Zustände 0 und 
-1. Ist 1 sinnvoller als -1?

Die signed/unsigned-Deklaration ändert nichts an der Breite des 
Datentyps (fügt also im signed-Fall kein Vorzeichen-Bit hinzu) sondern 
beeinflusst lediglich die Interpretation des Bitmusters (und damit 
verbunden implizite Typumwandlungen durch den Compiler).

Christian

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Konsequent bedeutet nicht immer sinnvoll.

Speziell in diesem Fall vermutlich eine echte Falle. Persönlich halte
ich mich mit signed oder unsigned nicht größer auf. Für mich ist ein
bit ein Bit, ein Byte ein Byte und gut isses ;)

Die Idee einer 1-Bit-Variable noch ein Vorzeichen zu verpassen halte
ich für gewagt (zumindest müßte dann ja ein Vorzeichenbit und eins
für die Stelle an sich vorhanden sein. Nur - wo ist es ?).

von Mathias (Gast)


Lesenswert?

Danke erstmal für die ganzen Erklärungen. Ich fand es nur seltsam, dass 
in der Beschreibung dauernd von unsigned char die Rede ist und dann im 
Beispiel wird nur unsigned verwendet. Und wiederum hab ich nun schön 
öfters gelsen, dass man lieber uint8_t verwenden sollte. Da kommt man 
echt durcheinander und weiß nicht was man nehmen soll (jedenfalls als 
Anfänger).


Mathias

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Nimm unsigned. Das signed mag zwar konsequent sein, aber ...

von max (Gast)


Lesenswert?

Joachim Drechsel schrieb:
> (zumindest müßte dann ja ein Vorzeichenbit und eins
> für die Stelle an sich vorhanden sein. Nur - wo ist es ?)

Die fehlen die Grundlagen.
Schaue mal in Google, Wikipedia, einem Fachbuch oder dem Ort deiner Wahl 
nach den verschiedenen Vorzeichenbehafteten Datenformaten. dort wirst du 
neben Vorzeichenbit auch auf Konstrukte wie 1er und 2er Komplement 
stoßen mit ihren vor und Nachteilen.

von Christian G. (christian_g83)


Lesenswert?

Joachim Drechsel schrieb:

> zumindest müßte dann ja ein Vorzeichenbit und eins
> für die Stelle an sich vorhanden sein. Nur - wo ist es ?).

Das "Vorzeichenbit" und "die Stelle" sind ein und dasselbe Bit. Die 
beiden Bit-Darstellungen "signed 1" und "unsigned 1" werden nur jeweils 
unterschiedlich interpretiert. Genauso wie bei einem Byte ein "signed 
0b10000000" und ein "unsigned 0b10000000" unterschiedlich interpretiert 
werden. Ersteres ist -128, letzteres 128. In beiden Fällen sieht die 
Bit-Darstellung identisch aus. Jetzt kann man nach und nach von rechts 
beginnend Bits abschneiden

signed 0b1000000 => -64
unsigned 0b1000000 => 64
...
signed 0b10 => -2
unsigned 0b10 => 2

bis man bei einem Bit landet.

Christian

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

max schrieb:
> Die fehlen die Grundlagen.

C ist mir durchaus geläufig.

von Christian G. (christian_g83)


Lesenswert?

Joachim Drechsel schrieb:
> C ist mir durchaus geläufig.

Das hat nichts mit C zu tun.

Christian

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Leute - es ging um Bitfelder nicht um Spitzfindigkeiten in der
Darstellung binärer Zahlen.

von Karl H. (kbuchegg)


Lesenswert?

Joachim Drechsel schrieb:
> Leute - es ging um Bitfelder nicht um Spitzfindigkeiten in der
> Darstellung binärer Zahlen.

Na,ja.
Du hast die Diskussion darüber eröffnet.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Joachim Drechsel schrieb:
> C ist mir durchaus geläufig.
Mir schon auch. Und trotzdem manchmal überraschend...  ;-)

Aber zum Glück haben die Zahlendarstellung und das Zweierkomplement nur 
ganz am Rande und fast gar nichts mit C zu tun...

von Karl H. (kbuchegg)


Lesenswert?

> Konsequent bedeutet nicht immer sinnvoll.

Und was soll das jetzt heißen?
Soll man die C-Definition so ändern:

In Bitfeldern kann man eine Anzahl von Bits zu einer Einheit 
zusammenfassen.
Diese 'Einheit' kann oder kann auch nicht ein Vorzeichen haben, es sei 
denn es handelt sich um ein einzelnes Bit, welches immer nur 'kein 
Vorzeichen' haben kann.

Wozu die Ausnahme? Braucht kein Mensch.
Wenn es einen Unterschied zwischen BitFeld1 und BitFeld2 in ...
1
struct Test
2
{
3
  unsigned  BitFeld1 : 3;
4
  signed    BitFeld2 : 3;
5
};
... gibt, dann ist es nur konsequent, wenn es genau den gleichen 
Unterschied auch bei ...
1
struct Test
2
{
3
  unsigned  BitFeld1 : 1;
4
  signed    BitFeld2 : 1;
5
};

... gibt. Aus welchem Grund soll die Bitzahl da einen Unterschied 
machen, ob BitFeld2 einmal korrekt und einmal ein Syntax Error sein 
soll? Weil dir das unsinnig vorkommt? Sorry, das ist mir als Begründung 
zu wenig, damit man es in eine ISO Norm mit aufnehmen sollte.

von Christian G. (christian_g83)


Lesenswert?

Joachim Drechsel schrieb:

> es ging um Bitfelder nicht um Spitzfindigkeiten in der
> Darstellung binärer Zahlen

OK. Jetzt hat es doch wieder mit C zu tun :)
1
#include <stdio.h>
2
3
struct
4
{
5
        signed flag:1;
6
} flags;
7
8
int main(void)
9
{
10
        flags.flag = 1;
11
        printf("%d\n", 42 * flags.flag);
12
        return 0;
13
}

Frage: Welche Zahl erscheint auf der Konsole?

Christian

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ich tippe auf -42

...CTRL-C.............CTRL-V...........

Und habe Recht:
http://codepad.org/TauApcR7

von Karl H. (kbuchegg)


Lesenswert?

Christian Gudrian schrieb:

> OK. Jetzt hat es doch wieder mit C zu tun :)
:-)


> Frage: Welche Zahl erscheint auf der Konsole?

Letzen Endes handelt es sich bei deinem Beispiel um die "Analogie in 1 
Bit" von
1
int main(void)
2
{
3
  signed char c;
4
5
  c = 128;
6
  printf("%d\n", c);
7
  return 0;
8
}


Du weist einer Variable einen Wert ausserhalb ihres Zahlenbereichs zu. 
Was soll da passieren?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Du weist einer Variable einen Wert ausserhalb ihres Zahlenbereichs zu.
Das -1 (Bit) wird für die Berechnung aufgebohrt zu einem "richtigen" -1 
(Integer), dann mit dem 42 (Integer) mutlipliziert und ausgegeben...

von Christian G. (christian_g83)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Du weist einer Variable einen Wert ausserhalb ihres Zahlenbereichs zu.

Und genau das wollte ich verdeutlichen: den Zahlenbereich eines 
vorzeichenbehafteten Bits.

Christian

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Die Physiker haben es ja auch geschafft, ein Proton in drie Quarks
zu zerlegen ... Auf ein Bit übertrgen könnte man noch gleich 2
Vorzeichen in einem Bit unterbringe :-)))

Ok, dann haben wir jetzt also ein Bitfield aus Vorzeichen.

von Christian G. (christian_g83)


Lesenswert?

Joachim Drechsel schrieb:

> Ok, dann haben wir jetzt also ein Bitfield aus Vorzeichen.

Genau. Vorzeichenbehaftete Bits können die Werte + und - annehmen, 
vorzeichenlose 0 und 1.

Christian

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Christian Gudrian schrieb:
> Genau. Vorzeichenbehaftete Bits können die Werte + und - annehmen,
> vorzeichenlose 0 und 1.

Was wiederum eine reine Frage der Interpretation ist.

von Karl H. (kbuchegg)


Lesenswert?

Lothar Miller schrieb:
> Karl Heinz Buchegger schrieb:
>> Du weist einer Variable einen Wert ausserhalb ihres Zahlenbereichs zu.
> Das -1 (Bit) wird für die Berechnung aufgebohrt zu einem "richtigen" -1
> (Integer), dann mit dem 42 (Integer) mutlipliziert und ausgegeben...

Schon klar.
Das ist das, was bei Verwendung eines 2-er Komplements passiert.

Aber aus Sicht des C-Standards, steht explizit im Standard, dass das 
Ergebnis unspezifiziert ist. Overflows (und im Grunde handelt es sich 
bei
   flags.flag = 1;
um einen Overflow) sind nur für unsigned Datentypen spezifiziert. Sobald 
signed im Spiel ist, hält sich der Standard aus jeglicher Interpretation 
raus.

Im 2-er Komplement ist der Wertebereich einer Zahl mit n Bit

   -(2^(n-1)) ... (2^(n-1)-1)        // ^ bedeutet 'hoch'

Bitzahl     -(2^(n-1))    (2^(n-1)-1)    Menge d. darstellb. Zahlen

  8           -128           127                256
  7            -64            63                128
  6            -32            31                 64
  5            -16            15                 32
  4             -8             7                 16
  3             -4             3                  8
  2             -2             1                  4
  1             -1             0                  2

und eine Zuweisung

    Variable = 2^(n-1)

ist ein Overflow, weil der positive Wertebereich nun mal nur bis 
(2^(n-1)-1) geht und 2^(n-1) im 2-er Komplement damit nicht 
darstellbar ist.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Christian Gudrian schrieb:
> Vorzeichenbehaftete Bits können die Werte + und - annehmen,
Was ist dann das Ergebnis von dem hier: 42 * -
Und was kommt heraus bei: 42 * +

Sieh dir das mal an: http://codepad.org/DXUGEwcT
Und dir wird klar:
- ein negatives vorzeichenbehaftetes Bit hat den Wert -1.
- ein "positives" vorzeichenbehaftetes Bit hat den Wert 0.
Es kann also die Werte 0 und -1 annehmen.

von Christian G. (christian_g83)


Lesenswert?

Lothar Miller schrieb:
> Es kann also die Werte 0 und -1 annehmen.

Das sagte ich bereits mehrfach.

Christian

von Christian G. (christian_g83)


Lesenswert?

Joachim Drechsel schrieb:

> Was wiederum eine reine Frage der Interpretation ist.

Ich sehe, wir verstehen uns. :)

Christian

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Christian Gudrian schrieb:
> Lothar Miller schrieb:
>> Es kann also die Werte 0 und -1 annehmen.
> Das sagte ich bereits mehrfach.
Partielle Amnesie?
Christian Gudrian schrieb:
> Vorzeichenbehaftete Bits können die Werte + und - annehmen
Die Null (in Zahlen 0) hat kein Vorzeichen...


Karl Heinz Buchegger schrieb:
> Overflows (und im Grunde handelt es sich
> bei
>    flags.flag = 1;
> um einen Overflow)
Richtig, das fehlende Vorzeichen hatte ich übersehen...  :-/

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Christian Gudrian schrieb:
> Ich sehe, wir verstehen uns. :)

Das ist mir schon klar :)

Ich verwende Bitfelder sehr selten (ich programmiere fast nur für
CGI/Windows), damit Speicher sparen bzw Ports adressieren ist eher
bei den kleine schwarzen Käfern angesagt. Da ist das recht praktisch
obwohl ich mir über die Performance da nicht ganz im Klaren bin.

Da muß ich mir mal genauer den Asembler-Output ansehen.

Jetzt erst mal eine Flasche Schampus köpfen - der Sack ist weg.

von max (Gast)


Lesenswert?

Joachim Drechsel schrieb:
> Ok, dann haben wir jetzt also ein Bitfield aus Vorzeichen.

Das ist leider ebenfalls nicht richtig. Es gibt hier kein Vorzeichenbit 
im Klassischen.

Du hast 0 und -1. Hättest du das Vorzeichen müsste es +1 und -1 sein. 
Nur dann könnte man das Vorzeichen auf einen anderen Wert durch 
Multiplikation übertragen.

Verabschiede dich von der Vorstellung des Vorzeichens als separate 
Information.

Gehe bei der Interpretation so vor:
Wenn das höchstwertige Bit 1 ist, so ist der absolute Wert einer signed 
ordinalen Variablen durch die Addition aller Bits multipliziert mit 
ihrem jeweiligen Wert gegeben. Ihr Vorzeichen ist Positiv.
Wert = + summe (from i=0 to bitbreite-1) über (bit(i) * 2 hoch i)

Wenn das höchstwertige Bit 1 ist, so ist der absoluter Wert einer signed 
ordinalen Variablen durch die addition aller invertierten Bits 
multipliziert mit ihrem jeweiligen Wert plus 1 gegeben. Ihr Vorzeichen 
ist Negativ.
Wert = - summe (from i=0 to bitbreite-1) über ((1-bit(i)) * 2 hoch i)

Du siehst in beiden Fällen wird zwar die Interpretation über das 
höchstwertige Bit gesteuert, jedoch ihr Wert über alle Bits (inklusive 
des höchstwertigen) gebildet.

Daher steckt in dem signed:1 := -1 tatsächlich die Information über Wert 
und Vorzeichen gemeinsam in dem einen Bit.

von max (Gast)


Lesenswert?

Im oberen Case muss es natürlich wenn ... 0 ist heissen

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Joachim Drechsel schrieb:
> Da ist das recht praktisch
> obwohl ich mir über die Performance da nicht ganz im Klaren bin.
Es lohnt sich nicht.
Ich nehme auch für jeden Eingang und für jedes Flag gleich ein ganzes 
Byte. Dadurch wird der Code schneller (Abfragen sind einfacher) und 
besser wartbar. Ich schreibe einfach ein neues Flag hin, und schere mich 
nicht darum, ob da noch irgendwo in einem Bitfeld Platz ist, oder wo ich 
das reinbasteln kann. Und gebe nicht die Kontrolle an den Compiler ab, 
der die Dinger legen darf, wie er lustig ist. Das hässlichste an den 
Bitfeldern ist aber, dass man keinen Pointer auf so ein Flag übergeben 
kann...

max schrieb:
> Es gibt hier kein Vorzeichenbit im Klassischen.
Es gibt kein "klassisches" Vorzeichenbit!
Man kann lediglich am MSB sehen, ob es eine negative Zahl ist.
Das Bit ist aber immer signifikant für den Wert der Zahl.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Lothar Miller schrieb:
> Es lohnt sich nicht.

Ich bin auch wieder davon abgekommen. Es ist zu umständlich. Wenn
die dann noch nicht mal 0 werden können ... Ohne Pointer ist das
sowieso nichts (ich nehme an, Du meinst Pointer auf die einzelnen
Bits).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Joachim Drechsel schrieb:
> ich nehme an, Du meinst Pointer auf die einzelnen Bits
Richtig.
Du kannst keine generische Funktion schreiben, immer nuß der 
Rückgabewert an das Bit zugewiesen werden...

von max (Gast)


Lesenswert?

Lothar Miller schrieb:
> max schrieb:
>> Es gibt hier kein Vorzeichenbit im Klassischen.
> Es gibt kein "klassisches" Vorzeichenbit!
> Man kann lediglich am MSB sehen, ob es eine negative Zahl ist.
> Das Bit ist aber immer signifikant für den Wert der Zahl.

Das ist das was ich schrieb.
"Im Klassisch" im Sinne von naiv, Gedankenbezogen, so wie es dies für 
andere Speicherarten, wie z.b. Ieee 754 existiert.

von Udo S. (urschmitt)


Lesenswert?

Lothar Miller schrieb:
> Es lohnt sich nicht.
> Ich nehme auch für jeden Eingang und für jedes Flag gleich ein ganzes
> Byte. Dadurch wird der Code schneller (Abfragen sind einfacher) und
> besser wartbar.

Das ist einer der Dinge die ich an Java mag. Saubere Typtrennung die 
dich dann auch zwingt sauber zu programmieren. Boolean hat true und 
false und man kann ihm auch keine 1 oder 0 zuweisen.

Solange das kein kleiner µC ist ist es auch sch...egal ob für ein 
boolean 1 byte verbraten wird.

Wobei ich natürlich nicht mit java µCs programmieren möchte, ganz klar!

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Saubere Typtrennung etcpp kann man machen wenn die Ressourcen auf
dem Zielsystem vorhanden ist, speziell Java ist da doch recht "üppig".

Auf einem ATTiny2313 (habe ich im Moment in der Mangel) würde das
wohl am Thema vorbei- und überhaupt nicht gehen.

Klar können mir in C auf diese Art Fehler passieren, ich habe aber
dann auch die Chance den zu beheben. Macht mir Java Mist, stehe ich
dumm da (gebranntes Kind, mir ist das mal bei dBASE IV passiert).

von Christian G. (christian_g83)


Lesenswert?

Udo Schmitt schrieb:

> Wobei ich natürlich nicht mit java µCs programmieren möchte, ganz klar!

Warum nicht?

Christian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Um auf die eingangs gestellte Frage zurückzukommen:

1 & 2 sind hier behandelt:
http://codepad.org/tU1MGQKt

3 ist irrelevant, weil mit 2 identisch (was ist uint8_t anderes als 
unsigned char, jedenfalls auf den üblichen Prozessorarchitekturen, die 
wir hier zu 99.95% verwenden?=

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Rufus Τ. Firefly schrieb:
> 1 & 2 sind hier behandelt:
> http://codepad.org/tU1MGQKt
Und 4 kommt raus, weil der Compiler dahinter offenbar ein 32 Bit 
Compiler ist (unsigned int = 32 Bit). Beim AVR-Studio kommt da beides 
mal 1 raus...

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

bei x eine int (32 Bit) bei y nur ein char (8 Bit) ?

von Udo S. (urschmitt)


Lesenswert?

Christian Gudrian schrieb:
> Warum nicht?

Weil ich mir da nicht Byte Code, ein Interpreter bzw. JIT-Compiler, 
dynamische Speicherverwaltung, garbage collector etc. pp. antun möchte.

Zumindest nicht auf 8 oder 16 Bittern.

Mein Einwurf mit java sollte eigentlich nur verdeutlichen daß C in 
Sachen Datentypen halt viel Schweinerei zulässt und daß es da 
'modernere' (nicht effizientere) Lösungen gibt für die ich froh bin.

Wir sollten hier aber kein Seitenthema Java versus C aufmachen.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Wieso "Schweinerei" ?

Effizient und funktioniert, was soll daran schlecht sein ?

von Udo S. (urschmitt)


Lesenswert?

Joachim Drechsel schrieb:
> Effizient und funktioniert, was soll daran schlecht sein ?
Man kann eine Mutter auch mit einer Säge lösen.
Nicht alles was funktioniert ist auch gut.

Diejenigen die beide Sprachen beherrschen haben verstanden was ich sagen 
will, auch wenn sie vieleicht anderer Meinung sind.
Wenn du jier ein Java versus C Bashing aufziehen willst dann ohne mich.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Bitfelder gibt es mW in Java nicht.

von Mathias (Gast)


Lesenswert?

@Lothar:
Bei meinem Watchfenster steht bei beiden Vars "not in scope" drin. Mache 
ich irgendwas falsch?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mathias schrieb:
> Mache ich irgendwas falsch?
Wo sitzt dein Breakpoint?
Meiner ist direkt auf der Zeile nach diesen Initialisierungen...

von Mathias (Gast)


Lesenswert?

Hmm immer noch nicht, kannst du mal deine main.c bitte posten.

von Karl H. (kbuchegg)


Lesenswert?

Mathias schrieb:
> Hmm immer noch nicht, kannst du mal deine main.c bitte posten.

Zeig doch mal deine.
Schliesslich hängt es von deinem Programm ab und wo genau du im Programm 
stehst, wenn du dir im Debugger eine Variable anzeigen lassen willst. Du 
Variable muss existieren. Eine funktionslokale Variable existiert aber 
ausserhalb ihrer Funktion nicht.

von Mathias (Gast)


Lesenswert?

1
struct {
2
   unsigned bStatus_1:1; // 1 Bit für bStatus_1
3
   unsigned bStatus_2:1; // 1 Bit für bStatus_2
4
   unsigned bNochNBit:1; // Und hier noch mal ein Bit
5
   unsigned b2Bits:2;    // Dieses Feld ist 2 Bits breit
6
   // All das hat in einer einzigen Byte-Variable Platz.
7
   // die 3 verbleibenden Bits bleiben ungenutzt
8
} x;
9
10
struct {
11
   unsigned char bStatus_1:1; // 1 Bit für bStatus_1
12
   unsigned char bStatus_2:1; // 1 Bit für bStatus_2
13
   unsigned char bNochNBit:1; // Und hier noch mal ein Bit
14
   unsigned char b2Bits:2;    // Dieses Feld ist 2 Bits breit
15
   // All das hat in einer einzigen Byte-Variable Platz.
16
   // die 3 verbleibenden Bits bleiben ungenutzt
17
} y;
18
19
int main(void)
20
{
21
    int sizofx = sizeof(x);
22
        int sizofy = sizeof(y);
23
24
    while(1)
25
    {
26
    }
27
}

von Karl H. (kbuchegg)


Lesenswert?

int main(void)
{
    int sizofx = sizeof(x);
        int sizofy = sizeof(y);


Compiler optimieren.
Eine Variable, die nicht lesend benutzt wird, braucht auch keiner.

Daher: sie fliegt raus.
Das spart SRAM und Rechenzeit.


-> Optimizer ausschalten oder irgendetwas einbauen, so dass die Variable 
benutzt wird und nicht wegzuoptimieren ist.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Da fehlt die Hälfte ...

So durfte das auch nicht zu kompilieren sein.

von Mathias (Gast)


Lesenswert?

Jo Danke, habs jetzt so gemacht.
1
int main(void)
2
{
3
    
4
  while(1)
5
  {
6
    int sizofx = sizeof(x);
7
    int sizofy = sizeof(y);
8
  }
9
}

von Karl H. (kbuchegg)


Lesenswert?

Mathias schrieb:
> Jo Danke, habs jetzt so gemacht.

Und?
Was soll das ändern?

Deine Variablen sizeofx bzw. y werden immer noch nirgends verwendet und 
sind damit Kandidaten zum wegoptimieren.

Schau:
Überleg dir einfach folgendes: Ändert sich das beobachtbare Verhalten 
(und damit ist nicht der Debugger gemeint), wenn man die Anweisungen 
einfach weglässt?

Bei dir: ja.

Es ist völlig egal, ob der sizeof an die Variable zugewiesen wird oder 
nicht. Deswegen ändert sich am Programmverhalten genau gar nichts. Ergo 
wird der Compiler das einfach weglassen wenn er optimieren darf.

von Karl H. (kbuchegg)


Lesenswert?

Noch ein Hinweis:
globale Variablen kann der Compiler nicht wegoptimieren.

von Mathias (Gast)


Lesenswert?

Aber ich hab doch Optimization ausgestellt. Danach waren immer noch 
keine Werte im Watch-Fenster. Nachdem ich dann das ganze in die Schleife 
reingemacht habe, hatte ich dann Werte. Einen Breakpoint nach den beiden 
zeilen konnte ich auch nicht setzen, denn da gabs immer ein 
Meldungsfenster.
Unzwar stand da folgendes:

"One or more breakpoints or tracepoints could not be set and have been 
disabled. The program has been stopped at the reset vector. Do you want 
to continue execution?"

von Karl H. (kbuchegg)


Lesenswert?

Mathias schrieb:
> Aber ich hab doch Optimization ausgestellt.

Das kann ich aber nicht wissen.

> "One or more breakpoints or tracepoints could not be set and have been
> disabled. The program has been stopped at the reset vector. Do you want
> to continue execution?"

Du hattest einen Breakpoint auf einer Zeile, die es so nach einer 
Programmänderung nicht mehr gab. Daher hat dich der Debugger darüber 
informiert, dass er den Breakpoint auflösen musste.

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Noch ein Hinweis:
> globale Variablen kann der Compiler nicht wegoptimieren.

Aber die Zuweisung. Nur global machen wird nichts ändern.
Global und volatile sollte aber helfen.

EDIT:
Ok, hiermit
> Aber ich hab doch Optimization ausgestellt.
hat sich dieser Zweig der Diskussion eh erledigt.

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.