Forum: Compiler & IDEs Komisch Globales mehrdimensionales array nicht verwendbar?


von KoF (Gast)


Lesenswert?

Hallo Leute,

ich habe ein Problem - was sonst.

Ich habe ein globales Array in einer Header definiert und das sieht so 
aus
1
...
2
#include <stdbool.h>
3
...
4
#define ARRAY_DEEP 4
5
bool E[ARRAY_DEEP][8]
6
...

Jetzt setzte ich das Array irgendwo im Programm in einer Funktion in 
etwa so:
1
void Test()
2
{
3
  E[0][0] = true;
4
  E[0][1] = false;
5
...
6
}

Wenn ich jetzt aber irgendwo anders im Programm (außerhalb von Funk. 
Test) auf das Array zugreife, steht z.B. in E[0][0], wie auch in E[0][1] 
"0"
Auch wenn ich E als const oder volatile definiere.

Andere Globale Variablen funktionieren hingegen nur eben diese Arrays 
nicht.

Compiler: GCC 3.4.4 (aus der Installation con Code::Blocks RC2)

Hat da jemand eine Idee, wo es aneckt?
mfg
KoF

von Falk B. (falk)


Lesenswert?

Muss man das nicht mit EXTERN definieren?

MFG
Falk

von KoF (Gast)


Lesenswert?

Ich wüßte nicht warum - außerdem gehen ja andere globale Variablen!

von Klaus F. (kfalser)


Lesenswert?

> Ich wüßte nicht warum -

Das muss anscheinend nichts bedeuten.
Die in einem Headerfile vereinbarten Variablen sollten eben schon mit 
"extern" deklariert werden, die Variable selbst wird dann in EINEM 
Quell-File definiert.
Dazu gibts Threads hier genug, in denen dies erklärt ist. Ob das die 
Ursache für das Nichterkennen des Arrays ist muss aber nicht sein.
Ist die Funktion, in der das Array falsch gelesen wird in der selben 
Datei wie Test oder in einer anderen?

von KoF (Gast)


Lesenswert?

Es ist eine andere Datei.

Komisch finde ich ja, das ich keinen Fehler bei der verwendung des 
Arrays zur  Compilezeit erhalte... ich also drauf lesend zugreifen kann, 
aber eben reingeschriebene werte nicht drinne stehen.

von yalu (Gast)


Lesenswert?

Wenn du die Header-Datei mit der Array-Definition in zwei
unterschiedlichen C-Dateien includest, werden zunächst einmal zwei
Array-Variablen angelegt die du getrennt schreiben und lesen kannst.
Allerdings haben beide Arrays den gleichen Namen (E), was der Linker
mit "multiple definition of `E'" anprangern sollte. Da du noch mit
3.4.4 arbeitest, hast du vielleicht auch einen etwas älteren Linker,
der sich möglicherweise anders verhält.

Wie auch immer: Doppelte Definitionen sind Käse. Definitionen in
Header-Files sind auch Käse, dort gehören nur Deklarationen hinein.
Mach's wie Klaus Falser geschrieben hat, dann bist du das Problem
höchstwarhrscheinlich los.

von Simon Kurz (Gast)


Lesenswert?

Solch ein Problem habe ich auch gerade, allerdings sieht das bei mir 
folgendermaßen aus:

main.c :
1
/* Global variables */
2
u16 AxisZeroG[3][3]; // AxisZeroG[Chip][Axis]

global.h
1
extern u16 AxisZeroG[3][3]; // AxisZeroG[Chip][Axis]

global.c
1
AxisZeroG[Chip][Axis] = (u16) Sum;

Bei der darauf folgenden Ausgabe erhalte ich immer 0! Deklariere ich das 
Array hingegen in der entsprechenden Funktion in global.c direkt, 
funktioniert alles!

von Oliver (Gast)


Lesenswert?

>Bei der darauf folgenden Ausgabe erhalte ich immer 0!

An den drei gezeigten Zeilen liegt das aber nicht. Die sind zunächst 
nicht verkehrt. Zeig doch mal den kompletten Code.

Oliver

von GLOBAL (Gast)


Lesenswert?

Wer globale Variablen benutzt und die dann auch noch im Header-File 
deklariert wird nicht unter lebenslangem Programmierverbot bestraft.

Schalte mal die Compiler-Warnings an !


...is mir übel ...

von Stefan E. (sternst)


Lesenswert?

GLOBAL wrote:
> Wer globale Variablen benutzt und die dann auch noch im Header-File
> deklariert wird nicht unter lebenslangem Programmierverbot bestraft.
>
> Schalte mal die Compiler-Warnings an !
>
>
> ...is mir übel ...

Was soll das? Warum sollte man globale Variablen-Deklarationen nicht in 
ein Header-File packen? Genau da gehören sie nämlich hin.

von Dieter (Gast)


Lesenswert?

lol, da wollte wohl einer klugscheißen und kennt aber selber nicht den 
unterschied zwischen Deklaration  und Definition^^

von Simon Kurz (Gast)


Lesenswert?

Einen Auszug des kompletten Codes kann ich heute Nachmittag posten (muss 
jetzt zum Zug) - es sei schon einmal so viel gesagt, dass es sich um 
einen ARM7-Prozessor Handelt (STR711).

von GLOBAL (Gast)


Lesenswert?

Noch so einer. Wer globale Variablen auch noch im Header-File definiert 
der sollte es ganz sein lassen. Warum benutzt ihr für euren 
"global"-Mist eigentlich nicht nur EINE Datei, EINE schöne große Datei 
in die man alles reinjauchen kann :-). Dann kommen hier auch nicht 
solche tollen Antworten und Kommentare und der Arbeitsplatz ist 
gesichert !

von Stefan E. (sternst)


Lesenswert?

GLOBAL wrote:
> Noch so einer. Wer globale Variablen auch noch im Header-File definiert
> der sollte es ganz sein lassen.

Ach, jetzt auf einmal "definieren", in deinem ersten Post war es noch 
"deklarieren".
Und der Fragesteller hat es im Header-File nicht definiert (zumindest 
nicht nach den paar Codezeilen, die er gepostet hat).

von Dieter (Gast)


Lesenswert?

> EINE schöne große Datei in die man alles reinjauchen kann...

Ob mit so einer Arbeitsweise der Arbeitsplatz gesichert wäre, wage ich 
ernsthaft zu bezweifeln!

von Suchender (Gast)


Lesenswert?

Wie handhabt ihr das denn, wenn ihr mehrere globale variablen in 
verschiedenen Dateien habt und benötigt diese auch in verschiedenen 
Dateien?

von Simon Kurz (Gast)


Angehängte Dateien:

Lesenswert?

So, ich habe aus den Dateien mal alles uninteressante herausgelöscht - 
wie gesagt: Wenn ich das so mache, wie in den Dateien (siehe Anhang) 
läuft das Programm --> Klar, in den Dateien fehlt jetzt natürlich alles 
Mögliche, was ich herausgelöscht habe, weshalb es natürlich NUR damit 
nicht funktioniert, aber das Prinzip wird klar)

Wenn ich nun die Zeile
1
u16 AxisZeroG[3][3]; // AxisZeroG[Chip][Axis]
 aus der global.c herauslösche und dieses Array so deklariere wie in 
meinem gestrigen Beitrag, steht in der Variable Buffer in dieser Zeile
1
UART_StringSend(UART0, Buffer);
immer 0!

von Stefan E. (sternst)


Lesenswert?

Du postest die funktionierende Variante? Klasse! :(
Dann können wir immer noch nur raten, wie die nicht funktionierende 
Version denn nun genau aussieht.

von Simon Kurz (Gast)


Angehängte Dateien:

Lesenswert?

Wenige Zeilen höher steht es zwar eindeutig, aber ich habe es noch 
einmal eingefügt.

von Stefan E. (sternst)


Lesenswert?

Simon Kurz wrote:
> Wenige Zeilen höher steht es zwar eindeutig, ...

Nein, da steht eben nicht, wo genau in main.c die Definition steht, 
oder ob du dich irgendwo vertippt hast, oder ...

Hast du wenigstens kontrolliert, ob diese Version auch tatsächlich den 
Fehler produziert? Oder hast du einfach nur den Sourcecode "aus dem 
Gedächtnis" geändert?

von Simon K. (simon) Benutzerseite


Lesenswert?

GLOBAL wrote:
> Noch so einer. Wer globale Variablen auch noch im Header-File definiert
> der sollte es ganz sein lassen. Warum benutzt ihr für euren
> "global"-Mist eigentlich nicht nur EINE Datei, EINE schöne große Datei
> in die man alles reinjauchen kann :-). Dann kommen hier auch nicht
> solche tollen Antworten und Kommentare und der Arbeitsplatz ist
> gesichert !

Ich weiß jetzt nicht in wie weit das ernst gemeint ist. Jedenfalls finde 
ich das "externieren" von globalen Variablen über ein Header File ganz 
und gar nicht schlimm.

Im Headerfile werden laut "Philosophie" ja die Schnittstellen zu einem 
Codemodul definiert. Bzw. Mithilfe eines Headerfiles kann man das 
machen. Und zu der Schnittstelle gehören meiner Meinung nach Funktionen 
genau so wie der Zugang zu globalen Variablen.

von GLOBAL (Gast)


Lesenswert?

Na gut, wann man den Buszugriff als Schnittstelle sieht kein Problem, 
dann liege ich total falsch, sorry nochmal !

Aja, da habe ich noch einen G

Viel Spass bei IRQ und Co. !

von Klaus (Gast)


Lesenswert?

> ...EINE Datei, EINE schöne große Datei
> in die man alles reinjauchen kann :-). Dann kommen hier auch nicht
> solche tollen Antworten und Kommentare und der Arbeitsplatz ist
> gesichert !

Bei einer dermaßen unstrukturierten Arbeitsweise wäre dein Job in meiner 
Firma alles andere als gesichert...

von Simon Kurz (Gast)


Lesenswert?

@Stefan Ernst: Ja, diese Version habe ich so (natürlich mit dem 
vollständigen Programmcode) geflasht und musste den Fehler feststellen - 
dies habe ich natürlich nicht nur einmal gemacht, sondern 
x-Möglichkeiten ausprobiert, bevor ich zunächst im Netz gesucht habe und 
schließlich hier gepostet habe.

Rein logisch sollte das ja auch so funktionieren - ich war auch sehr 
überrascht, dass es halt nicht geht!

von Simon Kurz (Gast)


Lesenswert?

Sehr merkwürdig - habe gerade mal getestet, ob ich die Variable Sum 
global in main.c deklarieren kann - damit verhält es sich genau so wie 
bei AxisZeroG!

Auch bei der Benutzung von Pointern, d.h. AxisZeroG wird als Pointer 
übergeben, kommt am Ende 0 heraus!

von Stefan E. (sternst)


Lesenswert?

Hast du überhaupt irgendwelche funktionierenden globalen Variablen?
Versuche doch mal folgendes in main.c:
1
...
2
int test;
3
4
int main(void)
5
{
6
...
7
  char buffer[20];
8
...
9
  test = 42;
10
  sprintf(buffer,"%p:%i",&test,test);
11
  UART_StringSend(UART0, buffer);
12
}

Wenn du auch hier eine Null bekommst, dann prüfe mal die Adresse. Gibt 
es dort überhaupt RAM? Vielleicht hast du ein Problem mit der Toolchain.

von Simon Kurz (Gast)


Lesenswert?

Ja, das habe ich mir gestern auch schon überlegt - dein Vorschlag war 
sehr gut - es ist natürlich wirklich so, dass auch hier der Wert 0 ist 
und die Adresse 0x6200090A ist! Diese Adresse liegt im Bereich des Ext 
Memory!

Eigentlich habe ich aber gar keinen Externen Speicher aktiviert...

von Stefan E. (sternst)


Lesenswert?

Dein Problem scheint also zu sein, dass der Linker das bss-Segment an 
eine falsche Adresse packt.

Ich kenne mich mit "gcc auf ARM" nicht aus. Du musst doch sicherlich den 
Controllertyp mit angeben, damit der richtige Startup-Code und das 
richtige Linker-Script ausgewählt werden, oder? Hast du vielleicht einen 
falschen Typ angegeben oder gar keinen?
Oder ist es eine Art generische Toolchain, bei der das alles "von Hand" 
angegeben werden muss? Dann liegt dort der Fehler.
Oder eine Toolchain speziell für diesen Controller, aber eben für eine 
Konfiguration mit externem Speicher? Dann könnte es reichen, das 
bss-Segment von Hand umzulegen.

PS: Das data-Segment wird dann wohl auch an einer falschen Adresse 
liegen.

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.