mikrocontroller.net

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


Autor: KoF (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich habe ein Problem - was sonst.

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

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

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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Muss man das nicht mit EXTERN definieren?

MFG
Falk

Autor: KoF (Gast)
Datum:

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

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: KoF (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Simon Kurz (Gast)
Datum:

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

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

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

global.c
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!

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: GLOBAL (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dieter (Gast)
Datum:

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

Autor: Simon Kurz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: GLOBAL (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 !

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Suchender (Gast)
Datum:

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

Autor: Simon Kurz (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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
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
UART_StringSend(UART0, Buffer);
immer 0!

Autor: Stefan Ernst (sternst)
Datum:

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

Autor: Simon Kurz (Gast)
Datum:
Angehängte Dateien:

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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: GLOBAL (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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. !

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Simon Kurz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Simon Kurz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du überhaupt irgendwelche funktionierenden globalen Variablen?
Versuche doch mal folgendes in main.c:
...
int test;

int main(void)
{
...
  char buffer[20];
...
  test = 42;
  sprintf(buffer,"%p:%i",&test,test);
  UART_StringSend(UART0, buffer);
}

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.

Autor: Simon Kurz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.