Forum: Compiler & IDEs undefined referenz to main


von Nebrelk (Gast)


Angehängte Dateien:

Lesenswert?

Guten Morgen!

Vielleicht hat ja einer Zeit und Lust sich das ganze Problem mal 
anzusehen.
Programm ist angehängt. Ob das ganz so läuft, sei mal dahin gestellt. 
Ich kann es leider erst gar nicht kompilieren. Kurz die Eckdaten:

- AVR Studio 4
- ATMega2560 ( bzw ARDUINO MEGA )
- Toolchain:
       avr-gcc : avr-gcc.exe
       make: make.exe
- Den [[undefined reference to 'main']] Beitrag, vom 9.12.07 habe ich 
gelesen. In meinem Makefile steht schon drin: SRC = $(TARGET).c.
- Auf avr-freak habe ich auch einen Beitrag gelesen, aber dort finde ich 
keine brauchbaren Informationen
- Nun der Fehler:

c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr6/crt 
m2560.o:(.init9+0x0):  undefined reference to `main'

Davor ist noch ein Warning:

../StateMaschineTest.c:300: warning: 'main' is normally a non-static 
function

Das Warning, werde ich vermutlich selber hinbekommen (fühlt euch 
trotzdem frei, mir dabei zu helfen ;-) ), aber den Error bekomme ich 
seit 2 Tagen nicht weg.

Wäre klasse, wenn ihr dafür kurz eure Zeit opfern könntet.

Gruß und Danke

von Peter II (Gast)


Lesenswert?

Nebrelk schrieb:
> Das Warning, werde ich vermutlich selber hinbekommen (fühlt euch
> trotzdem frei, mir dabei zu helfen ;-) )

dann mach das erstmal, dann wird auch der fehler vermutlich weg sein.


[...]
int main(void)
[...]
  return 0;
}
}
[...]

die 2 } }  sehen mir sehr merkwürdig aus.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:

> die 2 } }  sehen mir sehr merkwürdig aus.

Womit du nicht unrecht hast.

Einrückungen bei Klammern sind kein Selbstzweck und man sollte immer im 
Code bei Änderungen sofort die Einrückungshierarchie sofort nachziehen. 
Wenn wo die Klammern nicht stimmen, so wie hier, dann muss man das 
suchen.

Und man findet
1
void FillSendBuffer2(void)
2
/*
3
  Diese Funktion wird bei den Tests aufgerufen. In der Testroutine wird geprüft, ob die Anweisung zeitkritisch
4
  ist oder nicht. Im "temporären" Befehlsspeicher steht noch der aktuelle Befehl und kann von dort in den Sendepuffer
5
  von Uart 2 (zum Board1) geschoben werden. Ein kompleter String wird auf einmal übermittelt. Ist dies komplett geschehen, werden
6
  Sende Interrupts für Uart2 angestellt. (In der ISR wieder deaktiviert)
7
*/  
8
{
9
  //  (vorherige) Test wird nicht mehr ausgeführt
10
  //    |      Der Befehl ist komplet empfangen worden
11
  //    |          |
12
  if(!TestBusyFlag && CommandCompleteFlag)
13
  {
14
    uint8_t i = 0;
15
    do
16
    {
17
      Uart2SendBuffer.data[Uart2SendBuffer.write] = Befehlsspeicher[i];
18
      i++;
19
      Uart2SendBuffer.write++;
20
    } while ( Befehlsspeicher[i] != '\r' );
21
    // CR wird durch die do-while Schleife mit gesendet ?
22
    // Sende Interrupts an
23
    UCSR2B |= ((1<<TXEN2) | (1<<UDRIE2));
24
}

hier fehlt eine } die den if abschliesst.

Durch rücken alle nachfolgenden Funktionen als funktionslokale 
Funktionen in diese hinein und das Unheil nimmt seinen Lauf.

Und ja. Man darf Code ruhig auch zwischendurch mal compilieren und muss 
nicht Monster-Code in einem Rutsch schreiben, bei dem man dann vor 
lauter Tippfehler 2 Tage an der falschen Stelle nach dem Problem sucht.

von Nebrelk (Gast)


Lesenswert?

Danke für deine schnelle Hilfe.

Peter II schrieb:
> die 2 } }  sehen mir sehr merkwürdig aus.


Das sieht allerdings komisch aus. Habe ich entfernt. Leider ist der 
non-static Warning noch da und es kommen Errors hinzu:

../StateMaschineTest.c:378: error: static declaration of '__vector_29' 
follows non-static declaration
../StateMaschineTest.c:378: error: previous declaration of '__vector_29' 
was here
[...]
../StateMaschineTest.c:464: error: expected declaration or statement at 
end of input


Habe die Auslassungszeichen angefügt, da scheinbar jeder ISR Vector 
davon betroffen ist und ich denke, es macht wenig Sinn, 5 mal den (fast) 
gleichen Fehler zu posten. Falls nötig, mache ich das gerne.

Gruß

von Nebrelk (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Einrückungen bei Klammern sind kein Selbstzweck und man sollte immer im
>
> Code bei Änderungen sofort die Einrückungshierarchie sofort nachziehen.
>
> Wenn wo die Klammern nicht stimmen, so wie hier, dann muss man das
>
> suchen.
>
>
Habe ich eigentlich auch gemacht, glaube ich.

>
>
>
> hier fehlt eine } die den if abschliesst.
>
Ja! Das war der Fehler, vielen Dank!

>
> Durch rücken alle nachfolgenden Funktionen als funktionslokale
>
> Funktionen in diese hinein und das Unheil nimmt seinen Lauf.
>
>

Es wird vermutlich ein Copy-Paste Fehler sein. Ich habe das Programm in 
kleinen Schnippseln geschrieben, getestet und dann zusammen gefügt. 
Scheinbar an eine falsche Stelle. Deswegen waren unter der Main auch 2}.

>
> Und ja. Man darf Code ruhig auch zwischendurch mal compilieren und muss
>
> nicht Monster-Code in einem Rutsch schreiben, bei dem man dann vor
>
> lauter Tippfehler 2 Tage an der falschen Stelle nach dem Problem sucht.

Siehe oben. Ist eigentlich mehr oder weniger gemacht worden.


Danke! (Das oben soll nicht als beleidigte Rechtfertigung klingen).
Schön, dass es Leute wie euch gibt, die einem schnell und unkompliziert 
helfen können.

Gruß und einen schönen Tag noch!

von Karl H. (kbuchegg)


Lesenswert?

Nebrelk schrieb:
> Karl Heinz Buchegger schrieb:
>> Einrückungen bei Klammern sind kein Selbstzweck und man sollte immer im
>>
>> Code bei Änderungen sofort die Einrückungshierarchie sofort nachziehen.
>>
>> Wenn wo die Klammern nicht stimmen, so wie hier, dann muss man das
>>
>> suchen.
>>
>>
> Habe ich eigentlich auch gemacht, glaube ich.

Ja hast du. Grundsätzlich.

Aber du hast aus

}
}

keine Schlüsse gezogen.
Denn wenn die Klammerungen stimmen und die Einrückungen konsistent sind, 
dann KANN diese Konstellation nicht auftreten. Tut sie es doch, dann 
stimmt irgendwo davor etwas mit der Klammerung/Einrückung nicht. Und dem 
muss man nachgehen!
Jetzt hast du ja gesehen, wozu das führen kann. Wenn man das Problem 
dann identifiziert hat, dann kann man sogar hinten nach erklären, wie es 
zu der Fehlermeldung kommt. Aber die Umkehrung ist das Problem. Denn am 
Anfang weißt du ja das Problem nicht, sondern du hast nur die 
Fehlermeldung. Die führt dich aber (2 Tage lang) in die Irre. Das 
Problem ist ein ganz anderes, als du vermutet hast.

Daher: saubere und konsistente Einrückung ist kein Selbstzweck. Das 
'Problem' hat dir 2 Tage lang ins Gesicht gestarrt und wenn du die 
formalen Kriterien an den Code ernst genommen hättest, hättest du es 
gesehen / sehen müssen.

von Nebrelk (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Daher: saubere und konsistente Einrückung ist kein Selbstzweck. Das
>
> 'Problem' hat dir 2 Tage lang ins Gesicht gestarrt und wenn du die
>
> formalen Kriterien an den Code ernst genommen hättest, hättest du es
>
> gesehen / sehen müssen.

Ja, sehe ich ein. Da hätte ich einfach zuerst drauf schauen müssen, ob 
im Programm "Syntax"fehler vorhanden sind. Ich habe den (fehlerhaften) 
Code mal in einem sinnigeren Editor geöffnet, als dem von AVR Studios. 
In Notepad++ wurde mir mehr oder weniger direkt angezeigt, dass eine { 
Klammer nicht geschlossen wurde.
Vielleicht ist das auch eine Idee für die Zukunft, Code mit Notepad++ 
o.ä. zuschreiben und zwischendurch ins AVR Studio zu kopieren um es zu 
kompilieren. Durch die farbliche Markierung der Klammern bzw. 
Möglichkeit korrekt abgeschlossene Klammer ausdrücke zu verstecken, 
erhöht sich die Lesbarkeit deutlich, finde ich zumindest.
Oder hätte man das als "vernünftiger" Programmiere direkt sehen sollen / 
müssen.

Gruß

von Peter II (Gast)


Lesenswert?

Nebrelk schrieb:
> Oder hätte man das als "vernünftiger" Programmiere direkt sehen sollen /
> müssen.

ja hätte man. Das auf und zuklappen in den Editoren finde ich persönlich 
unsinnig. Ich will meinen code sehen. Die Warnung vom compiler hätte du 
halt nicht wirklich ignorieren sollen, dann hättest du es auch selber 
gefunden.

von Nebrelk (Gast)


Lesenswert?

Peter II schrieb:
> Die Warnung vom compiler hätte du
>
> halt nicht wirklich ignorieren sollen

Verbessert mich, wenn ich falsch liege: Die Warnung kam von einem 
Fehler, der sehr viel weiter oben im Code zu finden war. Deswegen hätte 
man den Fehler sicherlich finden können, es war aber nicht einfach. 
Empfand ich jedenfalls so (siehe 2 Tage erfolglose Suche im Internet und 
weit aus erfolglosere Versuche das Problem mit Hilfe von Anstarren des 
Bildschirms zu lösen).

Bleibt festzuhalten:

DANKE! Und ich werde mich in Zukunft bemühen, das Program einzurücken 
und draus entstehende Ungereimtheiten nicht zu ignorieren sondern ernst 
zu nehmen.

Erneut: Vielen Dank für die schnelle Hilfe.

von Peter II (Gast)


Lesenswert?

Nebrelk schrieb:
>> Die Warnung vom compiler hätte du
>> halt nicht wirklich ignorieren sollen
>
> Verbessert mich, wenn ich falsch liege: Die Warnung kam von einem
> Fehler, der sehr viel weiter oben im Code zu finden war. Deswegen hätte
> man den Fehler sicherlich finden können, es war aber nicht einfach.

das ist bei solchen Problemen immer der Fall. Hier hilft halt wirklich 
nur Erfahrung. Schön sind auch vergessen ; in einer headerdatei bei c++. 
Dabei kommen fehler die nicht wirklich auf das Problem hinweisen.

Aber diese Fehlermeldungen kennt man irgenwann und weiss wo man zu 
suchen hat.

Und bei

warning: 'main' is normally a non-static function

muss es irgendetwas mit der main zu tun haben, da aber der Syntax 
richtig war musste es ein anderes Problem sein, und dann sieht man 
eigentlich sofort das nach einem return 2 }} nicht stimmen können.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:

> Aber diese Fehlermeldungen kennt man irgenwann und weiss wo man zu
> suchen hat.

Genau das ist die "Krise" an der Sache.
Es gibt Fehlermeldungen, die sind irreführend.
Sie sind sachlich korrekt, indem sie den Fehler korrekt benennen. Aber 
der Fehler ist ein Folgefehler, die eigentliche Ursache ist eine andere. 
Daher muss man lernen, eine Fehlermeldung auch auf ihre Richtigkeit und 
Relevanz einzuschätzen.

>
> Und bei
>
> warning: 'main' is normally a non-static function
>
> muss es irgendetwas mit der main zu tun haben, da aber der Syntax
> richtig war

genau das ist der springende Punkt.
Man muss sein C soweit beherrschen, dass man einschätzen kann, ob die 
Fehlermeldung in sich stichhaltig ist.
Wenn der Linker mault, dass er kein main() finden kann, im Code aber 
unzweifelhaft ein main() enthalten ist, dann kann die Fehlermeldung vom 
Linker so erst mal nicht stimmen (natürlich stimmt sie, aber es gab 
einen Nebeneffekt, der dafür sorgte).


Das ganze hat ein bischen was von der 'Kuh Elsa'
http://de.wikipedia.org/wiki/Die_Kuh_Elsa
http://www.didipage.de/service/sketche/diekuhelsa/index.html

Natürlich ist die Kuh Elsa gestorben, weil das Dach auf sie drauf 
gefallen ist. Aber das ist nur das Endprodukt einer langen Kette von 
Ereignissen, die letztendlich dazu geführt haben. Der eigentliche 
Auslöser war ein ganz anderer.

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.