Forum: Compiler & IDEs Statische Structur als Classmember


von Hermann E. (hermann_e)


Lesenswert?

Mal 'ne Frage:

Offensichtlich gibt es da was was ich noch nicht richtig verstanden 
habe:
Mein Verständniss is folgendes: Wenn ich in einer Klasse eine Variable 
als "static" definiere ist der Wert dieser Variablen in allen von der 
Klasse abgeleiteten Objekten gleich. (Es gibt also nur eine Instanz 
dieser Variablen)

Ich habe jetzt folgendes Problem:

struct Mot
{
 uint8_t v1;
 uint8_t v2;
};

class MyClass
{
  static Mot M1;

  uint8_t v3;
      .
      .
};

//----------- Instantinierung der Objekte -------
MyClass C1;
MyClass C2;


Mit obig gesagten würde ich denken dass es in allen Instanzen von 
MyClass nur eine in allen Objekten identische Instanz von M1 gibt.
Dem scheint aber nicht so zu sein. Wenn ich mir die Sache im Simulator 
anschaue kriege kann ich locker den Variavblen v1 und v2 von M1 in C1 
andere Werte zuweisen wie denjenigen von M1 in C2.
Offensichtlich wirkt das Zauberwort "static" nicht so wie ich es erhofft 
hatte.
Googlen ergibt zwar jede Menge Info über statische Variablen in Klassen 
(wie Eingangs erwähnt), habe aber zu dieser präzisen Fragestellung 
nichts gefunden.
Gibt es da draußen jemand der mir damit auf die Sprünge helfen könnte ?

Danke:  Hermann

von Christian (Gast)


Lesenswert?

Genau das, was du erwartest sollte funktionieren. Da ist etwas mit einem 
Teil deines (nicht geposteten) Codes falsch.

Auf statische Variablen kannst du ja auch komplett ohne Objekt 
zugreifen, mit MyClass::M1.v1 = 5; zB.

von Hermann E. (hermann_e)


Lesenswert?

Christian schrieb:
> Genau das, was du erwartest sollte funktionieren. Da ist etwas mit einem
> Teil deines (nicht geposteten) Codes falsch.

Der Code umfasst mehrere Seiten, dass wollte ich niemanden antun und 
habe deshalb das Wesentliche so zusammengefasst

> Auf statische Variablen kannst du ja auch komplett ohne Objekt
> zugreifen, mit MyClass::M1.v1 = 5; zB.

Schon klar, aber irgendwie funzt das bei mir nicht. Ich werde mal mein 
Minimalprogramm durch den Simulator schicken, aber erst später da ich 
erst mal mit ein paar Kumpels einen heben gehe.

Soweit mal Danke und mehr später:  Hermann

von Hermann E. (hermann_e)


Lesenswert?

Die Neugier war einfach zu gross:
1
//==========================================
2
/*
3
 * StaticStructure.cpp
4
 *
5
 * Created: 06/02/2014 19:25:20
6
 *  Author: Admin
7
 */ 
8
// replaced -std=gnu99 against "-x c++ -std=gnu++98" in 
9
// ctrl+F7 -> C-Compiler -> Miscellaneous
10
11
#include <avr/io.h>
12
13
struct Mot
14
{
15
  uint8_t v1;
16
  uint8_t v2;
17
};
18
class MyClass
19
{
20
  public:
21
  static Mot M1;
22
  uint8_t v3;
23
};
24
//----------- Instantinierung der Objekte -------
25
int main(void)
26
{
27
  MyClass C1;
28
  MyClass C2;
29
  
30
   C1.M1.v1 = 2;  // compiler error 1
31
   C2.M1.v1 = 3;  // compiler error 2
32
  
33
  MyClass::M1.v1 = 2; // compiler error 3
34
  
35
  C1.v3 = 1;
36
  
37
    while(1)
38
    {
39
        //TODO:: Please write your application code 
40
    }
41
}
42
//============================================
weit komm' ich da nicht: Der Compiler würgt mir mit
1
"Error1 undefined reference to `MyClass::M1'" sofort eine rein.
Ohne die Zeilen:
1
        C1.M1.v1 = 2;  // compiler error 1
2
        C2.M1.v1 = 3;  // compiler error 2
3
  
4
       MyClass::M1.v1 = 2; // compiler error 3
Läuft die Compilierung aber ok. Ist da noch etwas anderes falsch was ich 
gerade nicht sehe  ??

Hermann

von Karl H. (kbuchegg)


Lesenswert?

Hermann E. schrieb:

> weit komm' ich da nicht: Der Compiler würgt mir mit
>
1
> "Error1 undefined reference to `MyClass::M1'" sofort eine rein.
2
>

Das ist aber der Linker, der dir eine reinwürgt.

Die Sache ist die. In der Klasse hast du nur eine Deklaration und keine 
Definition.
Nur weil du in der Klasse ausgedrückt hast, dass es eine Struktur geben 
soll, die im Namensraum der Klasse existiert, heist das noch lange 
nicht, dass es die Struktur dann auch tatsächlich gibt.

Das ist ein bischen so, wie:
nur weil du eine class geschrieben hast, hast du noch lange kein Objekt 
davon.

-> Du musst die static class member auch mal irgendwo definieren. 
NOrmalerweise macht man das im CPP File, welches zur Klasse gehört, denn 
wie immer gilt: es kann nur einen geben
1
struct Mot
2
{
3
  uint8_t v1;
4
  uint8_t v2;
5
};
6
class MyClass
7
{
8
  public:
9
  static Mot M1;
10
  uint8_t v3;
11
};
1
// und hier ist sie dann tatsächlich. Die statische struktur,
2
// die sich alle Objekte teilen
3
4
Mot MyClass::M1;

von Christian (Gast)


Lesenswert?


von Dr. Sommer (Gast)


Lesenswert?

Hermann E. schrieb:
> weit komm' ich da nicht: Der Compiler würgt mir mit"Error1 undefined
> reference to `MyClass::M1'" sofort eine rein.
Das ist kein Compilerfehler, sondern ein Linkerfehler. Du musst den 
Speicher für die statische Variable noch anlegen, z.B.:
1
class MyClass
2
{
3
  public:
4
  static Mot M1;
5
  uint8_t v3;
6
};
7
Mot MyClass::M1;
Diese Definition gehört in eine .cpp Datei und nicht in eventuelle 
Header, da du sonst mehrere gleichnamige Variablen definieren würdest...

von Hermann E. (hermann_e)


Angehängte Dateien:

Lesenswert?

Wow, dat war fix.
Ihr habt ja völlig recht, natürlich muss der Compiler für M1 erst noch 
im Speicher Platz machen (in meinem Originalcode habe ich das auch getan 
aber hier klar verschusselt).

Ich habe deshalb jetzt noch die Zeile
"Mot MyClass::M1 = {0};" in der Zeile direkt überhalb von Main() 
eingefügt und in der Tat motzt der Compiler nicht mehr. Ich komme jetzt 
aber zu dem von mir gennanten Problem:
Die Zeile "C1.v3 = 1;" habe ich eingefügt um mir einen Breakpoint im 
Simulator zu gönnen.
Was ich dann an dieser Stelle kriege ist im beigefügten Screenshot zu 
erkennen: Die Werte von C1.M1.v1 und die von C2.M1.v1 sind nicht nur 
unterschiedlich sondern auch völlig falsch !?

von Dr. Sommer (Gast)


Lesenswert?

Hermann E. schrieb:
> Die Werte von C1.M1.v1 und die von C2.M1.v1 sind nicht nur
> unterschiedlich sondern auch völlig falsch !?
Vielleicht mag der Simulator kein "static"... Versuch mal den Inhalt von 
"MyClass::M1" anzuzeigen

von Hermann E. (hermann_e)


Lesenswert?

Muß jetzt wirklich los !

Mehr später:  Hermann

von Christian (Gast)


Lesenswert?

Guck dir im Debugger mal die Adressen an, an denen Die Variablen liegen. 
Das sieht komisch aus.

Schieb die Adressen mal in eine Variable und guck die dann die Werte mal 
im Debugger an.

von Karl H. (kbuchegg)


Lesenswert?

Dr. Sommer schrieb:

> Vielleicht mag der Simulator kein "static"...

Das würde ich auch so sehen.
Das ist ein Fehler im Debugwerkzeug. Die dort angegebenen Adressen 
können nicht stimmen. Und damit sind dann auch die Wert unsinnig.

von Hermann E. (hermann_e)


Lesenswert?

Dr. Sommer schrieb:
> Versuch mal den Inhalt von
> "MyClass::M1" anzuzeigen

Ausprobiert, so zeigt er den korrekten Wert an !

Zum Überprüfen habe ich das Ganze nochmals mit einem anderen 
Debugger/C++ Compiler durchgespielt (letzte Version von TDM-GCC-32 under 
CodeBlocks)
und siehe da es funktioniert wie erhofft wenn ich mir den Ablauf im 
Debugger so anschaue(C1 und C2 haben nur eine gemeinsame und identische 
M1 Instanz).

Es handelt sich wohl um einen Bug im Debugger (das Wortspiel musste 
jetzt sein) und hoffentlich nicht im Compiler.

Kennt ihr irgendwelche Wege Atmel auf dieses Problem aufmerksam zu 
machen ?

Danke für eure Mithilfe:  Hermann

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.