www.mikrocontroller.net

Forum: Compiler & IDEs wie C-Programm abschließen?


Autor: Günther (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Mein Compiler (avr-gcc) neigt etwas zur Nörgelei.
Wenn ich am Ende einer Funktion (z.B. main() )
nach der letzten Anweisung ein Semikolon setze,
dann eine Leerzeile lasse und schließlich die schließende
geschweifte Klammer, also
      Anweisung ;

}  /* Ende main */


dann  quittiert er das mit der Fehlermeldung
parse error before  „}“  token.

Wenn ich es, ich weiß nicht wie, geschafft habe, dann kommt
wenigstens, aber diesmal nur als Warnung, der Hinweis:
Contol reaches end of non-void function

Wie muß denn ein Programm gcc-gerecht enden?
In meinen Büchern über C-Programmierung enden die
Beispiele so wie oben und irgendwelche speziellen Hinweise
habe ich trotz langen Suchens nirgends gefunden.
Kann mir jemand helfen?

Günther

Autor: Divison (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist dein Quellcode vieleicht zu lang? ISt vieleicht viel weiter unten
noch ne Klammer?

Oder ist es ist ein Fehler weiter oben in dem Programm. Hatte auch
schon das Problem, das ich eine Klammer irgendwo im Quelltext nicht
richtig hatte, er aber unten gemeckert hat.

#include <stdlib.h>
int main(void)
{
   while (1){
   //Endlosschleife
   }
}

Da kommt bei mir das raus. Also keine Feheler

set -e; avr-gcc -MM -mmcu=at90s8535 -I. -g -Os -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wa,-adhlns=leer.lst  -std=gnu99 leer.c \
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > leer.d; \
[ -s leer.d ] || rm -f leer.d

-------- begin --------
avr-gcc (GCC) 3.3.1
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.


Compiling: leer.c
avr-gcc -c -mmcu=at90s8535 -I. -g -Os -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wa,-adhlns=leer.lst  -std=gnu99 leer.c -o leer.o

Linking: leer.elf
avr-gcc -mmcu=at90s8535 -I. -g -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -Wall -Wstrict-prototypes
-Wa,-adhlns=leer.o  -std=gnu99 leer.o   --output leer.elf
-Wl,-Map=leer.map,--cref -lm

Creating load file for Flash: leer.hex
avr-objcopy -O ihex -R .eeprom leer.elf leer.hex

Creating load file for EEPROM: leer.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O ihex leer.elf leer.eep

Creating Extended Listing: leer.lss
avr-objdump -h -S leer.elf > leer.lss

Creating Symbol Table: leer.sym
avr-nm -n leer.elf > leer.sym

Size after:

    Flash     SRAM     EEPROM
    -----     ----     ------
       1%       0%         0%


Errors: none
-------- end --------

Autor: Divison (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist das mal mit meinem makefile.

Kannste ja mal ausprobieren.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also so ein quatsch!

int
main(void)

Muss natürlich IMMER mit einem return enden, da diese Funktion ja
schliesslich was zurückliefern soll!

int
main(void)
{
  bla...;
  while(1);

  /* NEVERREACHED */
  return 0;
}

Wenn die Funktion nichts liefern soll, dann MUSS man main als void
deklarieren:

void
main(void)
{
  bla...;
  while(1);
}

Dann gibts allerdings die Warnung: "return type of `main´ is not
`int´", die man dann ignorieren darf (oder man schaltet sie mit
-Wno-main aus).

Gruß,
Patrick...

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
GCC besteht übrigens nicht auf dem nicht erreichbaren return, d. h.

int
main(void)
{

  for (;;) {
    ..
  }
}

wird nicht angemeckert.

Das »void main()« sollte man sich besser gar nicht angewöhnen, es ist
vom Standard schlicht nicht vorgesehen.  Spätestens, wenn man mal C++
machen möchte, ist alles andere als

int main(void);

oder

int main(int, char **);

ein Fehler.

Autor: Divison (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ging doch um das beenden der main funktion, und nicht was sie
zurückliefern soll.

@oldbug -->  Was erzählst du denn dann da? Recht haste ja, aber darum
ging es doch garnicht.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Divison
Natürlich ging es darum!
Das fehlende return ist doch Ursache dieser Fehlermeldung!
Nicht, daß das jetzt in den falschen Hals gerät, das ist absolut nicht
böse gemeint!

@Jörg
Das trifft aber nur auf avr-gcc zu, nicht wahr?

@allgemein
Der einzige Grund, warum void main(void) verwendet, war mir lange
schleierhaft. Irgendwann habe ich dann mal gelesen, daß man damit ein
Stackframe spart... Ob das Sinn macht, oder nicht, liegt dann demnach
wohl im Auge des Betrachters :-)

Gruß,
Patrick...

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.: ...ums noch deutlicher zu machen: das return 0; beendet in
meinem Beispiel die Funktion main()
Eine Funktion als "nicht void" zu deklarieren und kein return
einbauen ist in meinen Augen einfach nur falsch...

Gruß,
Patrick...

Autor: Divison (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm

das ist nicht ganz richtig was du da sagst. Ein return gibt immer nur
einen Wert zurück. Mehr nicht. Es beendet keine Schleifen oder
Bedingungen oder sonst irgendwas.

Das Ende der Mainfunktion ist schlichtweg die }.

Wenn die Funktion main kein return hat, dann gibt sie halt nix zurück.
Kann fehler machen beim errorhandling aber wen das nicht stört.

Meine int main oben hat auch kein return 0. Geht aber prima! Würde mich
auch arg wundern wenn nicht.

Ach ja ich hab das nicht in den falschen hals bekommen. Sind ja hier
alle gross genug um Kritik zu ertragen. Dafür sind wir ja auch mitunter
hier.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da würd ich mich aber jetzt mal nicht drauf verlassen, daß Deine
Funktionen ohne return NICHTS zurück geben!
Mach mal folgendes:

int
testfunktion(void)
{
  /* gar nichts machen! */
}

int
main(void)
{
  printf("%d\n", testfunktion());
}

Vielleicht erstaunt Dich das Ergebnis ja ;)

Gruß,
Patrick...

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.