Wieso nimmt man eigentlich immer int main(void) und nicht Typ char? In der Regel geht es nur noch um einen Rückgabewert 0 oder 1 und selbst wenn man einen anderen Wert übergeben wollte, würde char doch ausreichen?
Weil es eben Fälle gibt, in denen ein Char nicht ausreicht. Du kannst halt frei definieren, was dein Programm zurück gibt. Wenn dein Programm irgendwas zählt, dann kann das z.B. ein Zählwert sein, der größer als ein Char ist. Wobei größer als int dann natürlich auch nicht geht.
Stefanus kj schrieb: > und nicht Typ char? Stefanus kj schrieb: > würde char doch ausreichen? möglicherweise weil "CHAR" zu unspezifisch ist? returncodes (zumindest innerhalb von SHELL scripten) sind typscherweise im Berich [0 .. 255]. Du bräuchtest also zumindest "unsigned char" (bei einem 8-bit Zeichensatz auf deinem Zielsystem) Sebastian R. schrieb: > Wenn dein Programm irgendwas zählt, dann kann das z.B. ein Zählwert > sein, der größer als ein Char ist. Ich denke nichtm das es eine gute Idee ist, einen Werte-Parameter (z.B. Zählwert) als Return-Code zurück zu geben.
:
Bearbeitet durch User
gut dann eben uchar...das meinte ich auch, also Werte von 0.254
Weil der C-Standard das so vorschreibt: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf S. 13: The function called at program startup is named main. [...] It shall be defined with a return type of int ...
Thomas M. schrieb: > also Werte von 0.254 0..255. Alles was draüber hinaus geht wird "Modulo" abgehackt.
Stefanus kj schrieb: > Wieso nimmt man eigentlich immer int main(void) und nicht Typ char? Weil es so im Standard steht. > In der Regel geht es nur noch um einen Rückgabewert 0 oder 1 und selbst > wenn man einen anderen Wert übergeben wollte, würde char doch > ausreichen? Nur in deiner begrenzten Weltsicht. Wenn man einen negativen Wert zurückgeben will (-1 ist gängig für "Fehler"), dann reicht char regelmäßig nicht aus, weil char je nach Plattform ganz legal unsigned sein kann. Bei int hingegen ist garantiert, daß es ein signed Typ ist. Auf einem µC ist das sowieso alles akademisch, weil es nichts gibt, das den Rückgabewert von main() lesen und etwas damit anfangen könnte.
spannendes Thema Es ist Montag, aber mache haben anscheinend schon WE
Thomas M. schrieb: > gut dann eben uchar Was ist denn uchar? Einer der Typen char16_t oder char32_t welche in der <uchar.h> definiert werden? Axel S. schrieb: > Auf einem µC ist das sowieso alles akademisch, weil es nichts gibt, das > den Rückgabewert von main() lesen und etwas damit anfangen könnte. Der Startup-Code könnte das, ist aber unüblich. Da auch auf PC-Betriebssystemen die main() nur indirekt aufgerufen wird (z.B. von einer Funktion _start), wird der Return-Wert da auch noch einmal durchgereicht, z.B. an den exit-Syscall.
Axel S. schrieb: > dann reicht char > regelmäßig nicht aus, weil char je nach Plattform ganz legal unsigned > sein kann. manchmal ist char unsigned - aber ganz sicher nicht regelmäßig, eher selten
"Weil der C-Standard das so vorschreibt:" Was ist denn das für eine Erklärung?! WEIL ES SO IST.... Sorry..aber das erklärt z.B,. nicht weshalb das als Standard genommen wurde.. Also dann für die für die es einfach der Standard ist...wieso?
"Was ist denn uchar?" rate mal was damit gemeint sein könnte..macht man umgangssprachlich, Worte abzukürzen...
Weil ein int die Größe eines MC Registers hat und der return Wert in einem Register an den Startup Code zurückgegeben wird. Du sparst mit einem Char überhaupt nichts.
Stefanus kj schrieb: > Wieso nimmt man eigentlich immer int main(void) und nicht Typ char? > In der Regel geht es nur noch um einen Rückgabewert 0 oder 1 und selbst > wenn man einen anderen Wert übergeben wollte, würde char doch > ausreichen? Weil der Aufrufer erwartet, daß ein int, also 16 oder 32 bit, zurückkommen, und nicht nur 8 bit und der Rest uninitialisiert und damit zufällig ist.
Axel S. schrieb: > Stefanus kj schrieb: >> Wieso nimmt man eigentlich immer int main(void) und nicht Typ char? > > Weil es so im Standard steht. > Und dass es so im Standard steht, deutet darauf hin, dass es durchaus Anwendungen gab, bei denen char oder unsigned char nicht gereicht hätte (z.B. OpenVMS, dass tatsächlich den ganzen 32 Bit, die ein int auf diesem System hat, Bedeutung im Rückgabewert gibt). Auch wenn bei den heute üblichen POSIX-Systemen ein unsigned char ausreichend wäre. > […] > > Auf einem µC ist das sowieso alles akademisch, weil es nichts gibt, das > den Rückgabewert von main() lesen und etwas damit anfangen könnte. Auf µC ist die C-Implementierung ja üblicherweise freestanding, womit Name und Typ der Startfunktion Implementierungsabhänging sind. Bei SDCC wird üblicherweise void main(void) verwendet, auch wenn SDCC auch mit ein paar anderen Varianten zurechtkommt. Philipp
Der Standard schreibt es so vor, weil es systemspezifisch ist, welche Rückgabewerte vom Host verarbeitet werden können. Während unter den meisten Unixen der Rückgabewert auf den Bereich 0-255 beschnitten wird, kann Windows z.B. den vollen Bereich von int als Rückgabewert verwenden und definiert auch eine ziemlich umfangreiche Liste von Error codes: https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes
Thomas M. schrieb: > Was ist denn das für eine Erklärung?! WEIL ES SO IST.... "Warum macht man das so" ist eine andere Frage als "Warum steht das im Standard so". In C macht man eine ganze Reihe von Dingen, weil sie vom Standard so vorgeschrieben sind, deren Sinn auch eher fragwürdig ist. Zwecks Kompatibilität zu bestehenden Systemen muss man das halt so machen. Thomas M. schrieb: > Also dann für die für die es einfach der Standard ist...wieso? Vermutlich weil "int" historisch einem Prozessor-Register entsprach und deshalb am Effizientesten übergeben werden kann; daher wird es in C und insbesondere dem POSIX-API ja auch für alle möglichen Werte benutzt. Das stimmt dann z.B. bei AVR oder AMD64 aber nicht mehr. Thomas M. schrieb: > rate mal was damit gemeint sein könnte..macht man umgangssprachlich, > Worte abzukürzen... C ist aber keine Umgangssprache. Man sollte schon präzise ausdrücken was man meint. Ich hätte von "uchar" jetzt auf <uchar.h> gefolgert.
Andersherum gefragt: Warum sollte man für einen ganzzahligen Rückgabewert etwas anderes als den gewöhnlichsten aller Ganzzahltypen, nämlich int nehmen? Minimale Vorteile hätte char oder unsigned char allenfalls bei 8-Bit-Prozessoren, aber die waren nicht die Zielarchitektur bei der Entwicklung von C.
Danke, das erste mal seit langem wieder brauchbare Antworten in diesem Forum und kaum Ausreißer. Na eben wenn es aber um AVR geht, würde ja char reichen, klar geht es nicht un ein Byte hier oder dort..aber als Anfänger macht es wohl Sinn sowas zu hinterfragen und nicht einfach möglichen fehlerhaften Lehrmeinungen nachzulaufen Durch sowas werden einmal falsch in die Welt gesetzte Meinungen sonst immer wieder fortgetragen, eben weil jemand es EINFACH SO MACHT...das finde ich immer sehr fragwürdig...
:
Bearbeitet durch User
1 | #define uchar unchar char
|
2 | #define unchar unsigned
|
3 | #define unchar_uchar uchar // wegen der besseren Lesbarkeit
|
4 | #define unchar_main unchar main
|
5 | unchar_main() { |
6 | }
|
Man sollte aber auch an die Watbarkeit denken und und den abweichenden Typ von main() klar+deultich kennbar anmachen
Sorry kleiner Fehler, so ist es richtig
1 | #define uchar unchar char
|
2 | #define unchar unsigned
|
3 | #define unchar_uchar uchar // wegen der besseren Lesbarkeit
|
4 | #define unchar_main unchar_uchar main
|
5 | unchar_main() { |
6 | }
|
Thomas M. schrieb: > Na eben wenn es aber um AVR geht, würde ja char reichen, ?!? Auf einem AVR gibt es überhaupt niemanden, der sich für den Rückgabewert interessiert. Da kannst du void oder char hinschreiben, wenn du returnst, dann ist sowieso alles im Arsch.
ach herje..hör doch mal mit dem uchar auf..das war doch nur eine Abkürzung da ich auf dem Handy im Forum geschrieben hatte ;-)
ja, aber auch darüber regen sich ja wieder andere auf wenn man void main(void) schreibt.. +Irgendwie regen sich bei C eigentlich alle immer über alles auf weil irgendwie immer alles falsch oder nicht so richtig richtig ist....jaja...schreibt ein Pascal/Delphi Anwender ;-) Wir brauchen jetzt aber keine C/Deplphi Diskussion darauf wollte ich nicht hianus, tief im innern wissen sowieso alle das Pascal besser ist hehe ;-)
Thomas M. schrieb: > Durch sowas werden einmal falsch in die Welt gesetzte Meinungen sonst > immer wieder fortgetragen, eben weil jemand es EINFACH SO MACHT...das > finde ich immer sehr fragwürdig... Man programmiert aber nicht nach "Meinung". Man programmiert danach, was zum System passt. Und wenn man C programmiert, arbeitet man nach dem C-Standard; die Compiler erwarten C-Standard-konformen Code von dir. Du kannst zwar auch deine eigene Meinung eingeben, aber das wird dann nicht immer so gut funktionieren. Die Überleitung von C-Programmieren zu Nazivergleichen ist... gekonnt. Lesbarkeiter schrieb: > #define unchar unsigned Hurra, endlich ist "unchar int" gültige Syntax und kein Compiler-Fehler mehr! Benutz doch wenigstens typedef ...
Thomas M. schrieb: > ja, aber auch darüber regen sich ja wieder andere auf wenn man void > main(void) schreibt.. Weil es einfach absolut keinen Grund dafür gibt. "int main" kostet praktisch nicht oder sogar absolut nichts. Dafür verstößt "void main" nicht nur gegen die Konvention, sondern ist ungültiges C. Mir fallen drei Gründe für "void main" ein. 1. Es handelt sich nicht um C. 2. Der Programmierer lehnt sich in pubertärem Trotz gegen diese dummen anderen Programmierer auf. 3. Der Programmierer weiß es nicht besser.
Walter K. schrieb: > Axel S. schrieb: >> dann reicht char >> regelmäßig nicht aus, weil char je nach Plattform ganz legal unsigned >> sein kann. > manchmal ist char unsigned - aber ganz sicher nicht regelmäßig, eher > selten Nun, auf Plattformen, bei denen char unsigned ist, ist char immer unsigned. Und immer ist meiner Meinung nach ziemlich oft... Axel S. schrieb: > Wenn man einen negativen Wert > zurückgeben will (-1 ist gängig für "Fehler"), dann reicht char > regelmäßig nicht aus, weil char je nach Plattform ganz legal unsigned > sein kann. Bei int hingegen ist garantiert, daß es ein signed Typ ist. ... und das dürfte tatsächlich der wahre Grund sein: main() wäre nicht mehr portabel. Je nachdem, ob char auf der gewählten Plattform signed oder unsigned wäre, würde main mal positive oder mal negative Returnwerte ausspucken. Und das wäre ziemlich eklig. Andererseits ist ein int definiert mit der "natürlichen Größe" für einen Datentyp einer bestimmten Architektur. Was wäre natürlicher, als den Datentyp mit natürlicher Größe als Rückggabewert für main() zu verwenden?
Dussel schrieb: > Dafür verstößt "void main" > nicht nur gegen die Konvention, sondern ist ungültiges C. Nein. Im Gegensatz zum "hosted environment" ist für ein "freestanding environment" (das ist das, worüber man auf einer µC-Seite üblicherweise redet) Name und Typ der Funktion, die beim Programmstart gerufen wird "implementation defined". Da darf es ein void main(void) also durchaus geben.
Thomas M. schrieb: > Na eben wenn es aber um AVR geht, ... must du dir keine Sorgen machen: Die allermeisten AVR-Programm laufen sowieso in einer Endlosschleife. Der AVR-GCC (getestet mit 8.2.0) erkennt dies und lässt dann die Instruktionen für den Rückgabe des Funktionswerts weg, auch wenn main als int deklariert ist.
Markus F. schrieb: > Dussel schrieb: >> Dafür verstößt "void main" >> nicht nur gegen die Konvention, sondern ist ungültiges C. > > Nein. > > Im Gegensatz zum "hosted environment" ist für ein "freestanding > environment" (das ist das, worüber man auf einer µC-Seite üblicherweise > redet) Name und Typ der Funktion, die beim Programmstart gerufen wird > "implementation defined". Da darf es ein void main(void) also durchaus > geben. Meine Antwort bezieht sich natürlich nur auf Anwendungsprogramme und wurde sowieso total falsch verstanden. ;-) Nein, leider muss ich zugeben, dass ich falsch lag. :-( Danke für die Richtigstellung.
Aber mit dem Fehler stehe ich nicht alleine da. http://www.stroustrup.com/bs_faq2.html#void-main :-)
Yalu X. schrieb: > Thomas M. schrieb: >> Na eben wenn es aber um AVR geht, > > ... must du dir keine Sorgen machen: > > Die allermeisten AVR-Programm laufen sowieso in einer Endlosschleife. > Der AVR-GCC (getestet mit 8.2.0) erkennt dies und lässt dann die > Instruktionen für den Rückgabe des Funktionswerts weg, auch wenn main > als int deklariert ist. Da frag' ich mich gerade, was dein schlauer Compiler denn wohl wegoptimiert? - die Warnung, daß eine als int deklarierte Funktion keinen Rückgabewert hat? - das return-Statement, das Du gar nicht hingeschrieben hast? - Oder die "statement not reached"-Warnung, weil Du eins hingeschrieben hast, das nie ausgeführt wird? Die Compiler, die ich kenne (avr-gcc gehört zugegebenermaßen nicht dazu, aber Google hat gesagt, daß es da auch so ist) liefern Rückgabewerte (zumindest für integrale Typen) in Registern. In Registern steht am Ende einer Funktion üblicherweise was drin (ob gewollt oder nicht). Wie kann man das wegoptimieren? (das gilt natürlich nicht für Register-saves und -restores, die man sich natürlich sparen kann, wenn man weiß, daß eine Funktion nie zurückkehrt)
schön finde ich, wie meine einfachen Anfängerfragen doch öfter zu umfangreichen Diskussionen führe, was zeigt, das viele sich mit dieser durchaus recht unbedeutenden Frage, nie beschäftigt haben und die meisten es halt einfach nur tun weil es so ist :-)
Markus F. schrieb: > Yalu X. schrieb: >> Thomas M. schrieb: >>> Na eben wenn es aber um AVR geht, >> >> ... must du dir keine Sorgen machen: >> >> Die allermeisten AVR-Programm laufen sowieso in einer Endlosschleife. >> Der AVR-GCC (getestet mit 8.2.0) erkennt dies und lässt dann die >> Instruktionen für den Rückgabe des Funktionswerts weg, auch wenn main >> als int deklariert ist. > > Da frag' ich mich gerade, was dein schlauer Compiler denn wohl > wegoptimiert? Alles, was nach der Endlosschleife in main() kommt. > - die Warnung, daß eine als int deklarierte Funktion keinen Rückgabewert > hat? Kriegt man bei main() sowieso nicht. Das ist ein Sonderfall. Bilde dich mal weiter. > - das return-Statement, das Du gar nicht hingeschrieben hast? Dito. Auch das ist bei main() erlaubt. > - Oder die "statement not reached"-Warnung, weil Du eins hingeschrieben > hast, das nie ausgeführt wird? Eine solche Warnung würde ich erwarten. Aber im Kontext deiner Frage: Warnungen werden natürlich nicht "wegoptimiert".
Markus F. schrieb: > Da frag' ich mich gerade, was dein schlauer Compiler denn wohl > wegoptimiert? Ohne Endlosschleife werden zwei Register mit dem Returnwert befüllt und danach ein ret ausgeführt:
1 | int main(void) { |
2 | return 42; |
3 | }
|
1 | main: |
2 | ldi r24,lo8(42) |
3 | ldi r25,0 |
4 | ret |
Mit Endlosschleife wird die return-Anweisung wegoptimiert, da sie nie erreicht werden kann:
1 | int main(void) { |
2 | for(;;); |
3 | return 42; |
4 | }
|
1 | main: |
2 | .L2: |
3 | rjmp .L2 |
Markus F. schrieb: > Da frag' ich mich gerade, was dein schlauer Compiler denn wohl > wegoptimiert?
1 | int main( void ) |
2 | {
|
3 | while(true){ |
4 | PORTB = 1; |
5 | c4: 81 e0 ldi r24, 0x01 ; 1 |
6 | c6: 85 b9 out 0x05, r24 ; 5 |
7 | c8: fe cf rjmp .-4 ; 0xc6 <main+0x2> |
Axel S. schrieb: >> - die Warnung, daß eine als int deklarierte Funktion keinen Rückgabewert >> hat? > > Kriegt man bei main() sowieso nicht. Das ist ein Sonderfall. Bilde dich > mal weiter. Versuche ich. Meine Kopie des C99-Standards behauptet allerdings (in Anhang - "informative" - I), daß Warnings nicht Teil des Standards sind und da also jeder machen kann, was er will: "An implementation may generate warnings in many situations, none of which are specified as part of this International Standard." Ein Compiler, der vor was ganz anderem warnt, wäre also trotzdem konform.
Hans-Georg L. schrieb: > Weil ein int die Größe eines MC Registers hat und der return Wert in > einem Register an den Startup Code zurückgegeben wird. 1+
Markus F. schrieb: > Axel S. schrieb: >>> - die Warnung, daß eine als int deklarierte Funktion keinen Rückgabewert >>> hat? >> >> Kriegt man bei main() sowieso nicht. Das ist ein Sonderfall. Bilde dich >> mal weiter. > > Versuche ich. Meine Kopie des C99-Standards behauptet allerdings (in > Anhang - "informative" - I), daß Warnings nicht Teil des Standards sind Das war nicht mein Punkt. Sondern daß es in C legal ist, wenn man main() mit einem int Rückgabewert definiert, dann aber kein return Statement im Code hat. Insofern gibt es für den Compiler keinen Grund, eine Warnung zu erzeugen.
Hans-Georg L. schrieb: > Weil ein int die Größe eines MC Registers hat und der return Wert in > einem Register an den Startup Code zurückgegeben wird. Du sparst mit > einem Char überhaupt nichts. Falsch! Ein int ist definiert als mindestend 16 bit breit. Deswegen hat dieser auf einem AVR beispielsweise auch 16 bit, was nicht in ein Register passt.
Axel S. schrieb: > Sondern daß es in C legal ist, wenn man main() > mit einem int Rückgabewert definiert, dann aber kein return Statement im > Code hat. Siehste, jetzt habe ich doch was gelernt. Im Standard steht tatsächlich: "reaching the } that terminates the main function returns a value of 0." Das habe ich wohl bis dato überlesen, danke.
Thomas M. schrieb: > Na eben wenn es aber um AVR geht, würde ja char reichen, klar geht es > nicht un ein Byte hier oder dort..aber als Anfänger macht es wohl Sinn > sowas zu hinterfragen und nicht einfach möglichen fehlerhaften > Lehrmeinungen nachzulaufen Das ist keine Meinung, das ist die Sprachdefinition von C. Thomas M. schrieb: > +Irgendwie regen sich bei C eigentlich alle immer über alles auf weil > irgendwie immer alles falsch oder nicht so richtig richtig > ist.... Muss man sich halt an den Standard halten, dann passts. Wenn du dich an den Duden hälst und leserliches Deutsch produzierst, wird dich auch keiner mehr fragen ob du Legastheniker bist.
"wird dich auch keiner mehr fragen ob du Legastheniker bist." bin ich aber und nun?! Dämlicher Kommentar, weißt Du aber sicher selber...hoffe ich...
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.