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
  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 --------
  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...
  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.
  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.
@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...
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...
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.
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...
  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
Mit Google-Account einloggen
  Noch kein Account? Hier anmelden.
 Thread beobachten
 Thread beobachten Seitenaufteilung abschalten
 Seitenaufteilung abschalten