Forum: Compiler & IDEs MSPGCC: Komische Compiler-Fehler...


von Philipp B. (philipp_burch)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich hab' merkwürdige Probleme mit dem MSPGCC-Compiler. Ich bin 
eigentlich dabei, die EFSL (Embedded file system library) für den MSP430 
umzuschreiben. Im grossen und ganzen ja kein Problem, aber es scheint 
auf dieser Welt keinen MSP430-Compiler zu geben, der das Ding 
kompilieren kann. IAR hat so seine Probleme, gemäss CCE ist so ziemlich 
jede Zeile falsch und der MSPGCC liefert Fehler, die irgendwie einfach 
net logisch sind. Beispiel:
""tmp" undeclared" Code:
1
 FAT_File *tmp;
Hallo? tmp wird ja in eben dieser Zeile deklariert!
Allerdings ist das nur die Spitze des Eisbergs. Die Probleme scheinen 
alle in den Dateien "helper.h" und "helper.c" (im nächsten Post 
angehängt) zu sein.
Hier mal die Fehlermeldungen und Warnungen:

----------------------------------
Severity and Description  Path  Resource  Location  Creation Time  Id
`f' undeclared (first use in this function)  efsl_msp430/src/interfaces 
helper.c  line 50  1161634750093  19563
warning: implicit declaration of function `fclose' 
efsl_msp430/src/interfaces  helper.c  line 68  1161634750093  19570
`FAT_File' undeclared (first use in this function) 
efsl_msp430/src/interfaces  helper.c  line 59  1161634750093  19566
`file' undeclared (first use in this function) 
efsl_msp430/src/interfaces  helper.c  line 75  1161634750093  19573
`filename' undeclared (first use in this function) 
efsl_msp430/src/interfaces  helper.c  line 50  1161634750093  19565
`SEEK_END' undeclared (first use in this function) 
efsl_msp430/src/interfaces  helper.c  line 75  1161634750093  19574
`tmp' undeclared (first use in this function) 
efsl_msp430/src/interfaces  helper.c  line 59  1161634750093  19567
syntax error before '*' token  efsl_msp430/inc/interfaces  helper.h 
line 45  1161634750093  19559
syntax error before '*' token  efsl_msp430/inc/interfaces  helper.h 
line 47  1161634750093  19560
syntax error before '*' token  efsl_msp430/src/interfaces  helper.c 
line 48  1161634750093  19562
syntax error before '*' token  efsl_msp430/src/interfaces  helper.c 
line 71  1161634750093  19571
warning: implicit declaration of function `fgetc' 
efsl_msp430/src/interfaces  helper.c  line 66  1161634750093  19569
warning: implicit declaration of function `fopen' 
efsl_msp430/src/interfaces  helper.c  line 50  1161634750093  19564
warning: implicit declaration of function `fseek' 
efsl_msp430/src/interfaces  helper.c  line 75  1161634750093  19572
warning: implicit declaration of function `ftell' 
efsl_msp430/src/interfaces  helper.c  line 76  1161634750093  19575
warning: implicit declaration of function `perror' 
efsl_msp430/src/interfaces  helper.c  line 42  1161634750093  19561
warning: ISO C89 forbids mixed declarations and code 
efsl_msp430/src/interfaces  helper.c  line 60  1161634750093  19568
-------------------------------



Anscheinend hat er Probleme mit den Deklarationen der folgenden beiden 
Funktionen und ihren Prototypen:
1
void Fopen(FAT_File** f,eint8* filename)
2
{
3
 *f=fopen(filename,"r+");
4
 if(*f==NULL){
5
  perror("Fopen: ");
6
  exit(-1);
7
 }
8
}
und
1
int getFileSize(FAT_File* file)
2
{
3
 eint32 c=0;
4
 
5
 fseek(file,0,SEEK_END);
6
 c=ftell(file);
7
 return(c);
8
}
Auch in den anderen Funktionen in diesen Dateien wirft er Fehler, die 
hängen aber möglicherweise mit diesen beiden Funktionen zusammen...

Ich wäre sehr froh, wenn mir jemand sagen könnte, was an dem Code denn 
angeblich falsch ist, bzw. wie ich es hinkriege, dass der MSPGCC diese 
Lib kompilieren kann. Bin net so der C-Hai, daher fallen mir 
Ungereimtheiten auch net wirklich auf. Wär' ja alles verständlich, wenn 
es nicht etwas wäre, was bestimmt schon viele Male von anderen Compilern 
erfolgreich kompiliert wurde...

Ich hoffe mir kann jemand helfen und danke im Voraus
Philipp

von Philipp B. (philipp_burch)


Angehängte Dateien:

Lesenswert?

Hier noch die "helper.c".

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> (...) und der MSPGCC liefert Fehler, die irgendwie einfach
> net logisch sind. Beispiel:
> ""tmp" undeclared" Code:
>
> FAT_File *tmp;
>
> Hallo? tmp wird ja in eben dieser Zeile deklariert!

Ja, tmp wird da deklariert. Aber was ist "FAT_File"? Wo ist das 
deklariert?


Im übrigen solltest Du Fehlermeldungen/Warnungen immer von "oben herab" 
betrachten, der erste Fehler ist oft der entscheidende und der Rest sind 
nur Folgefehler.

Ohne debug.h und types.h zu sehen, kann man aber nur wenig Schützenhilfe 
geben.

von Philipp B. (philipp_burch)


Angehängte Dateien:

Lesenswert?

Oh sorry, hier sind mal alle Dateien. Geändert habe ich eigentlich nix, 
das ganze Ding ist der Code von der EFSL bei SourceForge. Ausser 
FAT_File, das hab' ich so beannt, davor hiess es einfach "File". Ich 
hab' den Namen geändert, um Probleme mit evtl. gleichheissenden 
Bezeichnern zu vermeiden. Hat leider auch nix geholfen, der Fehler ist 
der gleiche wie davor.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Zwar bindet helper.c die Datei helper.h ein, aber die wiederum bindet 
keine Headerdatei ein, in der der Typ "FAT_File" deklariert wird.

Deklariert wird der zweimal in efs.h und in file.h

Du solltest Dir das mit dem wer-bindet-wann-wo-welche-Headerdatei-ein 
nochmal genauer ansehen bzw. sinnvoll überarbeiten.

Warum bindest Du "helper.h" nur in "helper.c" und sonst nirgends ein? 
Warum bindest Du die Headerdateien, die Du in "helper.h" einbindest, 
nicht gleich in "helper.c" ein, wo sie auch hingehören?

von Philipp Burch (nicht angemeldet) (Gast)


Lesenswert?

Sorry wegen dem kurzen Post gestern, war etwas im Stress.
Also:
Du meinst also, dass er FAT_File nicht findet und als Fehler angibt, 
"tmp" sei nicht deklariert? Ist das ein Fehler des Compilers oder sowas? 
Allerdings ist der Fehler, dass FAT_File nicht deklariert ist ja etwas 
weiter unten...
Das "wer-bindet-wann-wo-welche-Headerdatei-ein" werde ich mir noch 
ansehn, scheint so als wäre das irgendwie etwas verkehrt. Was wäre denn 
eine gute Variante, damit sicher überall alles eingebunden wird? Macht 
es Sinn, alle Dateien von einer Datei aus einzubinden (Includes.h oder 
sowas) und die einfach überall einzubinden, oder ist das nicht so 
geschickt?

Jedenfalls schonmal danke für deine Hilfe, ich weiss jetzt jedenfalls 
schonmal, was ich mir genauer anschauen muss.

von Karl heinz B. (kbucheg)


Lesenswert?

> Was wäre denn eine gute Variante, damit sicher überall alles eingebunden
> wird?

Ganz einfach. Jede Einheit, egal ob Header oder C-File bindet
die Header mit ein, die sie selber braucht.

Wenn also in einem helper.h eine struct FAT_file benutzt
wird, und diese struct FAT_file in einem anderen Header
File file.h deklariert ist, dann bindet helper.h die file.h
mit ein.
Dadurch ist sichergestellt, dass derjenige, der seinerseits
helper.h einbindet sich nicht darum kümmern muss, welcher
Rattenschwanz an includes noch nötig ist um helper.h includen
zu können.

Dabei kann es natürlich zu dem Fall kommen, dass ein und dieselbe
Header-Datei bei der Compilierung eines *.c Files mehrfach
includiert wird. Die dabei entsehenden Schwierigkeiten kann
man mit Include-Guards umgehen:
Jede Header-Datei beginnt und endet so (am Beispiel einer
helper.h)

helper.h:
*********

#ifndef HELPER_H_INCLUDED
#define HELPER_H_INCLUDED

#include "file.h"

// Hier kommt dann der Inhalt der helper.h

#endif

file.h:
*******

#ifndef FILE_H_INCLUDED
#define FILE_H_INCLUDED

struct FAT_file {
  // bla bla
};

#endif


Damit ist sichergestellt, dass der Compiler bei der Compilierung
eines *.c Files:

helper.c:
*********

#include "helper.h"
#include "file.h"

void FAT_file was_weis_ich()
{
}

den Inhalt von file.h nur ein einziges mal zu Gesicht kriegt,
auch dann wenn helper.c die file.h inkludiert und über den
Umweg über helper.h nochmal.

Aber das Grundprinzip ist: Jeder bindet das ein, was er braucht.
Nicht mehr und nicht weniger.
Solche Alles-inkludieren-Rundumschlag-Header haben sich auf
lange Sicht nicht bewährt.

von Karl heinz B. (kbucheg)


Lesenswert?

Zu deinem Fehlermeldungen:
Interessant ist im Regelfall nur die erste Fehlermeldung.
Wird die korrigiert, so fallen oft eine ganze Menge anderer
Fehler weg. Wenn der Compiler durch einen Fehler 'den Faden verloren'
hat, dann kommen oft ne Menge Folgefehler.

> FAT_File *tmp;
> Hallo? tmp wird ja in eben dieser Zeile deklariert!

Die erste Fehlermeldung war:

>efsl_msp430/src/interfaces  helper.c  line 68  1161634750093  19570
> `FAT_File' undeclared (first use in this function)

Der Compiler konnte also mit FAT_File nichts anfangen. Er weis
nicht was das ist. Folgerichtig kann er auch keine Variablen
vom Typ FAT_File anlegen, da er ja nicht weis wieviele Bytes
dafür zu reservieren sind. Noch nicht mal einen Pointer. FAT_File
könnte ja auch ein Funktionstyp sein und niemand garantiert, dass
Funktionspointer und Datenpointer dieselbe Länge haben.
Da er also die Variable tmp nicht erzeugen kann, sind daher alle
Verwendungen von tmp ebenfalls illegal. Siehst du wie Eins zum
Anderen führt? Wie gesagt:
Konzentrier dich auf den ersten Fehler oder zumindest: frage
dich bei weiteren Fehlermeldungen ob das nicht ein Folgefehler
sein könnte, der durch Behebung eines früheren Fehlers ebenfalls
verschwindet.

Und schrecke nicht vor vielen Fehlermeldungen zurück: 90%
davon sind meist Folgefehler. Korrigiert man den ersten Fehler
so verschwinden 100 von den 120 Fehlermeldungen ganz von alleine.




von Karl heinz B. (kbucheg)


Lesenswert?

> warning: implicit declaration of function `fclose'

Diese Warnung (und alle anderen in weiterer Folge) allerdings
solltest du ernst nehmen.
Entweder hat da wer vergessen stdio.h zu inkludieren (in dem
Fall sollte man ihm das Compilermanual mal um die Ohren hauen,
dass er solche Warnungen ignoriert), oder mit deinem Compiler-
Setup stimmt was nicht.

von Philipp B. (philipp_burch)


Angehängte Dateien:

Lesenswert?

Also, hab' jetzt nochmal bissle rumprobiert. Ich hab' den Code nun 
soweit, dass ich bei einem Fehler angelangt wird (Lag wirklich an den 
Includes...). Allerdings wird's langsam relativ strub. Je nachdem wie 
fest ich optimieren lasse (O0 - O3) hat er andere "internal error"s. Bei 
O0 und O1 (Das erste Zeichen ist ein grosses o):
make: *** [src/debug.o] Error 1    efsl_msp430  line 0

Bei O2:
internal error: Segmentation fault  efsl_msp430/src  fs.c  line 179
make: *** [src/debug.o] Error 1    efsl_msp430  line 0

Und schliesslich bei O3:
Internal compiler error in verify_local_live_at_start, at flow.c:586 
efsl_msp430/src  fs.c  line 60
make: *** [src/debug.o] Error 1    efsl_msp430  line 0
Wenn ich ihn mit der gleichen Einstellung nochmal aufrufe gibt's auch 
noch folgende Warnung:
Error launching external scanner info generator (gcc -E -P -v -dD 
C:/Programme/eclipse/workspaces/.metadata/.plugins/org.eclipse.cdt.make. 
core/specs.c)     efsl_msp430  Unknown

In fs.c (Im Anhang) besteht Zeile 60 sowie 179 aus
1
}
Nix weiter, bei beiden ist es das Ende einer Funktion. Allerdings nicht 
der gleichen...

Die beiden "internal error"s könnten ein Bug des Compilers sein, muss 
ich dessen Erbauern wohl mal schreiben. Aber der andere Fehler "Error 1" 
ist eigenartig. In der Konsole steht da sowas:

--------------------
'Building file: ../src/debug.c'
'Invoking: mspgcc GCC C Compiler'
msp430-gcc -I"C:\Programme\mspgcc\msp430\include" -O0 -g3 -Wall -c 
-fmessage-length=0 -mmcu=msp430x169 -o"src/debug.o" "../src/debug.c" && 
\
  echo -n 'src/debug.d' src/ > 'src/debug.d' && \
  msp430-gcc -MM -MG -P -w -I"C:\Programme\mspgcc\msp430\include" -O0 
-g3 -Wall -c -fmessage-length=0 -mmcu=msp430x169  "../src/debug.c" >> 
'src/debug.d'
Das System kann den angegebenen Pfad nicht finden.
make: *** [src/debug.o] Error 1
--------------------

Und das mehr oder weniger für alle Dateien. Manchmal für ein paar mehr, 
manchmal weniger...

Ich blick's echt nicht mehr... Was kann das sein? Und WELCHEN Pfad kann 
er denn nicht finden? Ich weiss ja nicht was er mit 'src/debug.xy' 
anstellt, aber ich nehme schon an, dass er da im richtigen Verzeichnis 
sucht. Ansonsten existieren die Verzeichnisse ja...

Kann mir da auch jemand helfen?

von Philipp B. (philipp_burch)


Angehängte Dateien:

Lesenswert?

Weiss denn niemand was zu den Fehlermeldungen? Ich komm' echt nimmer 
nach. Ich hab' das ganze Ding jetzt mal mit IAR kompiliert und DAMIT 
GEHT'S! Aber warum? Das heisst ja, dass der Code jetzt in Ordnung ist, 
was hat der mspgcc also für komische Probleme damit?!
Im Anhang mal die gesamte Ausgabe der Konsole.

von Karl H. (kbuchegg)


Lesenswert?

> -o"src/plibc.o" "../src/plibc.c"

Das sieht seltsam aus. Das die *.c Files auf einem Verzeichnis
namens src liegen, ist noch logisch. Aber dass die Object-Files
auf ein anderes src Verzeichnis gehen, ist schon seltsam:
Zum einen ist es nicht dasselbe Verzeichnis, zum anderen heist
es ebenfalls src. Und das ist schon eher ungewöhnlich. Selbiges
mit den *.d files.

Deine Verzeichnis-Struktur muesste also so aussehen:

           was_weis_ich
            /           \
          src (1)       Projekt (3)
                          \
                         src (2)

(1) hier muessten die *.c Files zu finden sein
(2) hier enstehen die *.o und *.d Files
(3) hier liegt das makefile

Hast du die Struktur? Ich könnte mir vorstellen, dass
es das Verzeichnis src (2) nicht gibt und sich der Compiler
beschwert, dass er die Ausgabefiles nicht erzeugen kann.

Zu den internal Compiler-Errors:
Sowas ist immer blöd. Da hilft nur mit dem Code etwas spielen.
Dinge umstellen und hoffen, dass du das richtige erwischt.

von Philipp B. (philipp_burch)


Lesenswert?

Also, die Verzeichnisstruktur sieht so aus:

          Projekt-Ordner
           /  |       \
          /   |        \
        src  inc      Debug
        *.c  *.h      /   \
                     /     \
                   src  makefiles
                   *.o    *.mk

So gesehen eigentlich durchaus existierend, aber ob der da wirklich 
immer am richtigen Ort sucht? Und wie könnte man sowas denn umstellen?

>Zu den internal Compiler-Errors:
>Sowas ist immer blöd. Da hilft nur mit dem Code etwas spielen.
>Dinge umstellen und hoffen, dass du das richtige erwischt.

Na du machst mir Mut ;)

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Philipp Burch wrote:
>  *f=fopen(filename,"r+");

Das was du da kompilierst macht auf einem MSP430 keinen Sinn, das ist 
das "Hardwarelayer" für einen PC wo fopen & Co. zur Verfügung stehen.

Meine Meinung: EFSL ist unübersichtlich, unnötig komplex, schlecht 
dokumentiert, und hat ein zweifelhaftes API. Nimm lieber 
http://elm-chan.org/fsw/ff/00index_e.html.

von Philipp B. (philipp_burch)


Lesenswert?

Hui, danke für den Link Andreas! Das sieht schonmal sehr gut aus! 
Irgendwann hatte ich das schonmal gesehen, hab's aber dann leider wieder 
vergessen. Hätte mir womöglich einiges an Arbeit erspart, mal sehn...

PS: Sorry wegen dem falschen Forum.

von Philipp B. (philipp_burch)


Lesenswert?

So, hab's jetzt mit dem Code vom Elm-Chan gemacht. Sieht gut aus! War 
noch ein ordentlicher Kampf, bis ich den Debugger zum Laufen gekriegt 
hab'. Vielleicht sollte man im Artikel noch erwähnen, dass der u.U. 
nicht funktioniert, wenn die Pfade zu lang sind und/oder Leerzeichen 
beinhalten. Auf einem "neuen" Laufwerk ohne langen Pfad ging's dann 
plötzlich.

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.