Forum: Mikrocontroller und Digitale Elektronik Keil µV: Warning - sizeof returns zero


von Ralf (Gast)


Lesenswert?

Hallo,

ich programmiere mit Keil µVision. Ich habe eine C-Datei, in der neben 
einer Funktion auch eine Tabelle steht. Die Tabelle steht aus Gründen 
der Übersichtlichkeit am Ende der Datei, weil die Tabelle sehr groß ist. 
Ich greife in der Funktion auf die Tabelle zu, daher habe ich die 
Tabelle ganz oben deklariert. für den Zugriff benutze ich den 
sizeof-Operator. Beim Kompilieren warnt mich der Compiler, dass der 
sizeof-Operator 0 zurückliefert.

das ganze sieht etwa so aus (schreibe leider von einem anderen Rechner, 
daher kein Originalcode):
1
struct {
2
  int intDemo;
3
  char charDemo;
4
} stDemo;
5
6
extern stDemo Tabelle[];  //extern wg. Deklaration
7
8
void function(void) {
9
  char Count;
10
11
  Count = 0;
12
13
  do {
14
    <Zugriff auf Daten>
15
    Count++;
16
  } while(Count < sizeof(Tabelle) / 3);  //durch drei teilen, weil
17
                                         //stDemo 3 Bytes groß ist
18
}
19
20
...
21
<weitere Funktionen>
22
...
23
24
stDemo Tabelle[] = {
25
  0x00, 0xFFFF,
26
  0x01, 0xFFFE,
27
  0x02, 0xFFFD,
28
  <...>
29
  0xFD, 0x0002,
30
  0xFE, 0x0001,
31
  0xFF, 0x0000,
32
};

Eine Möglichkeit wäre, bereits bei der Tabellendeklaration die Größe 
einzutragen, aber dann muss ich immer an zwei Stellen ändern.

Hoffe, ich konnte mein Problem deutlich machen :-)
Hat jemand eine Idee, wie ich das lösen kann, so dass die Tabelle am 
Ende steht, und der sizeof-Operator trotzdem die richtige Größe ausgibt?

Danke

Ralf

von Jörg X. (Gast)


Lesenswert?

Schreib die Tabelle in eine extra Header-Datei und binde diese oben ein 
-- ist der Einzige Weg die Größe der Tabelle automatisch zur Verfügung 
zu haben.

"extern stDemo Tabelle[];" Sagt ja eben nichts über die Größe aus.

hth. Jörg

von Karl H. (kbuchegg)


Lesenswert?

Wenn du nur diesen Code Abschnitt hast ....
1
struct {
2
  int intDemo;
3
  char charDemo;
4
} stDemo;
5
6
extern stDemo Tabelle[];  //extern wg. Deklaration
7
8
void function(void) {
9
  char Count;
10
11
  Count = 0;
12
13
  do {
14
    <Zugriff auf Daten>
15
    Count++;
16
  } while(Count < sizeof(Tabelle) / 3);  //durch drei teilen, weil
17
                                         //stDemo 3 Bytes groß ist
18
}

... dann beantworte mal schnell die Frage:
Aus wievielen Elementen besteht das Array?

Genausowenig wie du diese Frage beantorten kannst, kann es
auch der Compiler nicht.

Merke: Der Compiler geht dein Programm von oben nach unten
durch. Und zwar nur ein einziges mal. Es ist deine Aufgabe
dafür zu sorgen, dass zum Zeitpunkt an dem eine Variable
verwendet wird, auch alle benötigten Informationen zu dieser
Variablen bereits vorher bekannt gegeben wurden.

von Helmi (Gast)


Lesenswert?

Aufgepasst wenn du durch 3 Teilst wenn du meinst deine Struktur haette 
nur 3 Byte groesse gilt das nicht fuer alle Compiler.

> } while(Count < sizeof(Tabelle) / 3);

je nachdem ob du einen 8/16/32 Bit Prozessor hast kann es sein das der 
Compiler die Anzahl der Bytes auf eine gerade Anzahl aufrundet wegen des 
Zugriffs. Aus deiner Angabe den uVison Compiler von Keil zu benutzen 
kann man nicht sehen welche CPU (8051,C166,ARM) du benuzt.

Solltest du in deiner Struktur wirklich nur die Byteanzahl haben wollen 
die angegeben hast dann must du deine Struktur so angeben:

struct {
  int intDemo;
  char charDemo;
} __packed stDemo

falls du einen ARM Prozessor hast

Gruss Helmi

von Karl H. (kbuchegg)


Lesenswert?

Helmi wrote:
> Aufgepasst wenn du durch 3 Teilst wenn du meinst deine Struktur haette
> nur 3 Byte groesse gilt das nicht fuer alle Compiler.
>
>> } while(Count < sizeof(Tabelle) / 3);

Ja da hat er recht.

> struct {
>   int intDemo;
>   char charDemo;
> } __packed stDemo
>
> falls du einen ARM Prozessor hast


Eine andere Lösung besteht darin, den Compiler die Größe
der Struktur bestimmen zu lassen.

>> } while(Count < sizeof(Tabelle) / sizeof(*Tabelle));

Damit ist man dann in allen Fällen auf der sicheren Seite.

von Ralph (Gast)


Lesenswert?

lösch die Zeilen weg :
struct {
  int intDemo;
  char charDemo;
} stDemo;

extern stDemo Tabelle[];  //extern wg. Deklaration

und setz an diese Stelle erst das #include xx.H und dann die Tabelle.

wenn du bei der Tabelledefinition in dir [] ein Define einträgst, dann 
musst du auch nur an einer Stelle ändern.
stDemo Tabelle[NUMBER_OF_ENTRYS] = {
  0x00, 0xFFFF,
  0x01, 0xFFFE,
  0x02, 0xFFFD,
  <...>
  0xFD, 0x0002,
  0xFE, 0x0001,
  0xFF, 0x0000,
};



in der xx.H datei :

#define NUMBER_OF_ENTRYS   256 /* die entsprechende Anzahl /*

struct {
  int intDemo;
  char charDemo;
} stDemo;

extern stDemo Tabelle[];



Das define NUMBER_OF_ENTRYS kannstdu dann auch in der While Schleife 
verwenden.
Wie oben aber auch schon erwähnt solltest du prüfen ob und wie der 
Compiler die Tabelleneinträge auf 32Bit Grenzen im Ram auffüllt.

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.