Forum: PC-Programmierung Deklaration von register union X x1, x2, x3, x4;


von Hans (Gast)


Lesenswert?

Ich bin neue in Embedded Welt und von vorne an habe ich verständnis 
Problem.

Prolematik:


Folgende Deklation habe ich :
  register union Timers aT1, aT2, aT3, aT4;

Was ist der Unterschied zu: unsigned char X  oder unsigned long X...?

Was wirkt die deklaration von register union X.

union: ist eine Art wie Struktur (struct und union unterscheiden sich 
abgesehen von der syntakt in der Art und Weise wie mit dem Speicherplatz 
der Daten umgegangen wird sonst nicht).
union wird auch eingesetzt um speicherplatzt zu sparen.

Mir geht es darum zu verstehen: wann und Warum benutzt man die oben 
genannten Deklaration?

 Danke

von Sebastian V. (sebi_s)


Lesenswert?

Eine union ist schon deutlich was anderes als ein struct. Bei einem 
struct kannst du jeder der Variablen nutzen, bei einer union teilen sich 
alle den gleichen Speicherplatz und du kannst nur eine der Variablen 
nutzen.

Das register Keyword drückt aus, dass der Compiler doch bitte versuchen 
soll die Variable in einem CPU Register zu speichern. Der Compiler muss 
sich aber keinsfalls daran halten. Eigentlich können die Comiler 
mittlerweile selbst ganz gut entscheiden welche Variablen in ein 
Register sollen. Also braucht man das register Keyword eigentlich auch 
eher selten.

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:

> union: ist eine Art wie Struktur (struct und union unterscheiden sich
> abgesehen von der syntakt in der Art und Weise wie mit dem Speicherplatz
> der Daten umgegangen wird sonst nicht).
> union wird auch eingesetzt um speicherplatzt zu sparen.

Das ist aber eine sehr krude Erläuterung, die am Wesen einer union nicht 
mal ansatzweise kratzt.

Eine Union ist eine logische Zusammenfassung von mehreren Membern, wobei 
die Besonderheit darin besteht, dass sich alle Member denselben 
Speicherbereich teilen. Sie sind quasi einander überlagert.

Daraus folgt allerdings auch: Es kann gesichert immer nur einen Member 
geben, dessen Daten intakt sind. Welchem Member auch immer als letztes 
etwas zugewiesen wurde, er belegt damit den Speicher. Wie andere Member 
diesen Speicher wahrnehmen und aus den Bytes im Speicher machen ist 
komplett undefiniert (mit einer Ausnahme: ein unsigned char Array)

register hingegen ist eine völlig andere Baustelle.

Die Speicherklasse 'register' stammt noch aus der Zeit, als die Compiler 
noch nicht besonders gut optimieren konnten und vor allen Dingen noch 
keine Datenflussanylsen machten. Mittels register teilte man dem 
Compiler mit, dass eine bestimmte Variable oft benutzt wird, und es sich 
daher um einen Kandidaten handelt, den er in einem CPU Register 
vorhalten sollte.
Heutzutage sind die Optimizer längst erwachsen und können viel besser 
als di meisten Programmierer entscheiden, welche Variablen zu welchen 
Zeitpunkten möglichst lange in CPU-Registern vorgehalten werden sollen. 
Die meisten COmpiler ignorieren heutzutage die Speicherklasse register 
und entscheiden lieber selber.

> Mir geht es darum zu verstehen: wann und Warum benutzt man die oben
> genannten Deklaration?

Wie immer gilt:
So etwas muss man immer im Kontext des verwendenden Codes betrachten.

von Daniel A. (daniel-a)


Lesenswert?

Karl Heinz schrieb:
> Daraus folgt allerdings auch: Es kann gesichert immer nur einen Member
> geben, dessen Daten intakt sind.

Ich benutze die Unions manchmal bei  Pseudovererbung zusammen mit 
Arrays, um nicht mehrere Arrays zu brauchen:
1
enum TYPE {
2
  TYPE_B = (1<<0),
3
  TYPE_C = (1<<1)
4
};
5
6
struct a {
7
  enum TYPE type;
8
};
9
10
struct b {
11
  struct a base;
12
  int x;
13
};
14
15
struct c {
16
  struct a base;
17
  char* x;
18
};
19
20
union un {
21
  struct a a;
22
  struct b b;
23
  struct c c;
24
};
25
26
union un x[2];
-
1
switch(x[0].a.type){
2
  case TYPE_B: {
3
    struct b* a = &x[0].b;
4
    a->x = 3;
5
  } break;
6
  case TYPE_C: {
7
    struct c* a = &x[0].c;
8
    a->x = "test";
9
  } break;
10
}

Ist soetwas noch zulässig? Kann soetwas irgendwo Probleme breiten?

von Hans (Gast)


Lesenswert?

Hallo Zusammen,

benutze Compile C18

wenn ich so eine marco habe:

#define A

und dann ich benutze dieses marco in inrgend eine Funktion einfach als 
Aufruf wie z.B:


int sum(int a,int b)
{
  A; // was für Value hat A?
  return a+b;
}


Danke

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:

> und dann ich benutze dieses marco in inrgend eine Funktion einfach als
> Aufruf wie z.B:

Du kannst ein Makro nicht 'wie einen Aufruf' benutzen.
Ein Makro
1
#define TEXT anderer_Text
leistet genau dasselbe, wie wenn du in deinem Editor den Menüpunkt 
"Ersetzen" anwählst, und dort eingibst, dass du den Text "TEXT" gegen 
den Text "anderer_Text" ersetzt haben willst.

Nur mit dem Unterschied, dass der Präprozessor jedesmal vor dem 
eigentlichen Compilerlauf die Ersetzung vornimmt.

> {
>   A; // was für Value hat A?

Was also ergibt sich in Zusammenhang mit dem Makro
1
#define A

Na, dann wird das A eben durch einen leeren Text ersetzt. Es ensteht
1
int sum(int a,int b)
2
{
3
 ;
4
  return a+b;
5
}

Das ist durchaus gültiges C. Das ist dann eben eine leere Anweisung an 
der Stelle entstanden.

Ein Makro wird nicht 'aufgerufen', sondern ein Makro sorgt dafür, dass 
ein Text durch einen anderen Text ersetzt wird. Wenn du dich also 
fragst, was da im Endeffekt passiert, dann ersetze einfach den im Code 
stehenden Text gegen den Ersatztext aus dem Makro und sieh dir an, was 
dabei dann raus kommt.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> leistet genau dasselbe, wie wenn du in deinem Editor den Menüpunkt
> "Ersetzen" anwählst, und dort eingibst, dass du den Text "TEXT" gegen
> den Text "anderer_Text" ersetzt haben willst.

genau genommen stimmt das so nicht.
Aber als erste Näherung kann man das so sagen.

von Hans (Gast)


Lesenswert?

Karl Heinz schrieb:
> #define TEXT anderer_Text

Mir ist auch schon klar.




Problem ist:

Ich habe so einen angefangene Projekt bekommen und ich muss ihm um Paar 
Funktionalitäten erweitern.

In eine Hauptfunktion sind viele Macros eingesetzt.
Dieses Macros sind  so definiert:

#define A
#define B
....


Diese Macro wurden in dieses Hauptfunktion wie z.B :

void tutwas()
{
  //....
  A
  ...
  //.....
  .....
}

so gerufen.

Da ich auch ziemlich neue in Embedded Welt  habe ich nicht der Sinn 
verstanden.

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:

> #define A
> #define B
> ....
>
>
> Diese Macro wurden in dieses Hauptfunktion wie z.B :
>
> void tutwas()
> {
>   //....
>   A
>   ...
>   //.....
>   .....
> }
>
> so gerufen.

Da hat sich wohl jemand ganz einfach ein paar 'Hooks' eingebaut um an 
bestimmten Stellen noch Anweisungen dazwischen zu setzen.

Zum Beispiel könnte man per Makro an die bewussten Stellen ein paar 
printf (oder das jeweilige sinnmachende Äquivalent) einschleusen um in 
der Debugphase da Ausgaben zu haben.
1
#define A  printf( "irgendwas\n" )

Nimmt man den Makros den Ersatztext weg
1
#define A

verschwinden auch die Ausgaben.

Ist jetzt nur eine mögliche Hypothese. Wenn ein Makro keinen Ersatztext 
hat und so wie gezeigt im Code verwendet wird dann hat es auch keine 
Funktion, weil an dieser Stelle einfach nur eine leere Anweisung 
entsteht. D.h. das Makro ist überflüssig. Wozu das Makro vorher mal 
gedient hat, kann man nur raten, aber ich schätze mal, irgend so ein 
Debug Mechanismus wird es wohl gewesen sein.

>
> Da ich auch ziemlich neue in Embedded Welt  habe ich nicht der Sinn
> verstanden.

Das hat mit der Embedded Welt nicht viel zu tun. Das ist einfach 
kreativer Einsatz der Möglichkeiten, die mir der Präprozessor bietet. Ob 
Supercomputer oder µC ist dabei völlig nebensächlich.

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.