Gültiges ANSI C?



  • irgendwie kann ich es gar nicht glauben, dass so etwas ein gültiges (ANSI C konformes) Programm ist:

    main()
    {
    	printf("Hello World!\n");
    }
    

    entspricht das Programm dem ANSI C Standard?



  • int main()
    {
       printf("Hello World!\n");
       return 0;
    }
    

    das hier würd ich sagen ist ANSI C Standard! oder?
    in meinem C++ Buch wird eher:

    main()
    {
        printf("Hello World!\n");
    }
    

    benutzt(vielleicht C++ Std.?).

    mfg hohesC



  • nein, C erlaubt diese Deklaration von main bei den meisten Compilern auch - afaik auch schon vor 1987.
    Trotzdem. Jede Funktion in C hat einen Typ und wenigstens einen Parameter und das sollte man auch schreiben..

    int main (int argc, char **argv)
    {
        return 0;
    }
    

    wäre die komplette Schreibweise. Lässt man das int vorne weg, nimmt der Compiler als Rückgabewert einfach int an. Genauso beim Return. Schreibt man dieses nicht, so nimmt der Compiler an, dass 0 zurückgeliefert wird.

    Die Argumente argc und argv kann man zwar auch weg lassen, aber sicherheitshalber sollte man sie doch drin lassen.



  • DocJunioR schrieb:

    Lässt man das int vorne weg, nimmt der Compiler als Rückgabewert einfach int an. Genauso beim Return. Schreibt man dieses nicht, so nimmt der Compiler an, dass 0 zurückgeliefert wird.

    Das stimmt so nicht! Ab ANSI C 1990 muss ein Rueckgabetyp deklariert werden. "Default int" gibt es ab diesem Standard nicht mehr -- jedoch gibt es immer noch Compiler, die die alte Syntax unterstuetzen. Und wenn "return" weggelassen wird, aber ein Rueckgabetyp deklariert ist, gibt der Compiler eine Warnung aus, und es wird ein zufaelliger Wert zurueckgegeben (auf Intel-Kisten meist das was gerade in Register EAX ist).

    In C gibt es keine Automatismen -- Du kriegst immer das, was Du programmiert hast. Das ist das schoene daran! 😉

    Fehlt ein "return", dann fehlt es eben. Der Compiler gibt dann zwar eine Warnung aus, uebersetzt es aber trotzdem. Du kannst Dir ja mal den Assembler-Quelltext einer Funktion erzeugen lassen (bei VC++ z.B. mittles "cl /c /Fa datei.c" von der Kommandozeile, erzeugt "datei.asm"), und dann siehst Du, dass der Compiler kein automatisches "return 0" generiert, sondern einfach gar nix; und da EAX (auf Intel-Kisten) meist das Rueckgabe-Register ist, gibt die Funktion das zurueck was gerade da drin steht (z.B. von der letzten Berechnung).

    DocJunioR schrieb:

    Die Argumente argc und argv kann man zwar auch weg lassen, aber sicherheitshalber sollte man sie doch drin lassen.

    Bei der Standard C Aufrufskonvention werden Parameter auf den Stack gelegt und nach Aufruf der Funktion wieder vom Stack entfernt. Dadurch ist es moeglich, eine Funktion auch ohne Parameter zu verwenden (z.B. mit "func(void)"), auch wenn sie mit Parametern aufgerufen wird.

    Wir hatten das Thema gestern im C++ Forum: ➡

    http://www.c-plusplus.net/forum/viewtopic.php?t=101764&postdays=0&postorder=asc&start=10



  • hohesC schrieb:

    in meinem C++ Buch wird eher:

    main()
    {
        printf("Hello World!\n");
    }
    

    benutzt(vielleicht C++ Std.?).

    Nein, ist auch kein C++ Standard. Da ist int als Rückgabetyp erforderlich. Und C++ und printf? 😮



  • und printf ohne stdio.h ?



  • Power Off schrieb:

    Ab ANSI C 1990 muss ein Rueckgabetyp deklariert werden.

    Ab C99

    Bei der Standard C Aufrufskonvention werden Parameter auf den Stack gelegt und nach Aufruf der Funktion wieder vom Stack entfernt. Dadurch ist es moeglich, eine Funktion auch ohne Parameter zu verwenden (z.B. mit "func(void)"), auch wenn sie mit Parametern aufgerufen wird.

    Nachtrag: der Caller ist für push und pop zuständig, das ermöglicht es unbestimmte Parameteranzahl zu haben, weil die Funktion selber nicht wissen muss wieviele parameter sie bekommen hat (der aufrufer räumt ja auf)

    @supertux:
    in älteren C Standards sind prototypen nicht notwendig: es wird dann automatisch

    func();
    als prototyp angenommen.

    deshalb ist ein
    char* p=(char*)malloc(10);
    ja auch so tückisch.



  • In C89 ist die Deklaration von Funktionen ohne explizite Angabe eines Rückgabetyps zulässig, da wird dann standardmäßig int benutzt. Das selbe gilt für Parameter, so wäre zum Beispiel

    foo(a, b) { ... }
    

    gleichbedeutend mit

    int foo(int a, int b) { ... }
    

    Der Hintergrund ist, dass in Prä-Standard-Zeiten Funktionsdeklarationen a la

    foo(a, s)
      int a, char const *s;
    {
      ...
    }
    

    durchaus gängig waren. Der aktuelle C-Standard (ISO-C99) lässt das allerdings nicht mehr zu. Auch definiert C99 nur zwei gültige Formen für main:

    int main(void); /* Nein, int main() reicht nicht */
    int main(int argc, char *argv[]); /* oder auch char **argv, das ist äquivalent */
    

    Diese werden vom Standard garantiert, bei allen anderen Signaturen ist es Glückssache, ob der Compiler den Kram annimmt.



  • > und printf ohne stdio.h ?

    ist das ein Korrektes C Programm oder muss ich hier noch <stdio.h> inkludieren?

    int main(void)
    {
        printf("Hallo Welt!");
    }
    

    wird impliziet bei der int main Funktion etwas züruckgegeben oder muss ich nur ein return 0 einfügen?

    (Ich finde es echt Furchtbar das selbst Autoren von Bücher über C nicht einmal ein Standardkonformes Buch schreiben können - wie soll man den das denn dann als Leser jemals können)



  • Vertexwahn schrieb:

    ist das ein Korrektes C Programm oder muss ich hier noch <stdio.h> inkludieren?

    Die stdio.h sollte schon erwähnt werden 🙂

    Vertexwahn schrieb:

    wird impliziet bei der int main Funktion etwas züruckgegeben oder muss ich nur ein return 0 einfügen?

    Du musst ein "return integer" angeben. Das integer muss natürlich nicht 0 sein. In C++ scheint es allerdings erlaubt zu sein, das "return integer" wegzulassen. Hat man mir zumindest gesagt 😉

    Vertexwahn schrieb:

    (Ich finde es echt Furchtbar das selbst Autoren von Bücher über C nicht einmal ein Standardkonformes Buch schreiben können - wie soll man den das denn dann als Leser jemals können)

    Ja, schon traurig. Wobei mich persönlich Dinge wie "void main(void)" weniger stören als ein C/C++ Mischmasch.

    Man sollte aber auch nicht zu sehr auf solchen Dingen rumreiten. Sehr häufig wird man in realen Anwendungsfällen ohnehin den Standard verlassen, und die heilige Kuh "Portabilität" schlachten müssen. Was natürlich keine Entschuldigung für drittklassige Lehrbücher sein soll.

    EDIT: Schraipfäler korrägirt



  • > In C++ scheint es allerdings erlaubt zu sein, das "return integer" wegzulassen. Hat man mir zumindest gesagt

    yup - in C++ kann man bei int main - das return 0 sparren - wird kein Return angegeben wird implizit 0 zurückgegeben

    wie sieht es den mit globalen Variblen in C aus die nicht initialisiert werden - besitzen diese einen standardmäßigen "nullwert" wie in C++?



  • Und C++ und printf?

    und printf ohne stdio.h ?

    1. nicht stdio.h in C++ sondern

    #include <cstdio> 
    
    main() 
    { 
    	printf("Hello, World!");
    }
    

    und 2. sollte das ein beispiel für die main-funktion in C++ sein wie Sie mein
    C++ Buch auch gebraucht.

    Ich weis das für

    printf("");
    

    in C die stdio.h benötigt wird!
    Es ging mir lediglich um den funtionskörper von main.

    mfg hohesC 🕶



  • hohesC schrieb:

    und 2. sollte das ein beispiel für die main-funktion in C++ sein wie Sie mein
    C++ Buch auch gebraucht.

    Das ist aber eher C als C++, denn in C++ nutzt man dafür std::cout. Wenn das so in deinem C++ Buch steht, hast du wahrscheinlich ein relativ schlechtes oder altes.



  • hohesC schrieb:

    #include <cstdio> 
    
    main() 
    { 
    	printf("Hello, World!");
    }
    

    Um...ne, C++ ist das nicht. In C++ musste das int schon explizit vor die main schreiben (ebenso in C99, main() allein haut nur in C89 und Prä-Standard-C hin). Und in C gibts keinen cstdio-header. In C schreibt man also

    #include <stdio.h>
    int main(void) {
      printf("Hello, World!\n"); // oder, besser: puts("Hello, World!");
    }
    

    In C++ dagegen

    #include <cstdio>
    int main() {
      printf("Hello, World!\n");
    }
    

    ...obwohl man in C++ wohl eigentlich doch eher

    #include <iostream>
    using namespace std;
    int main() {
      cout << "Hello, World!" << endl;
    }
    

    schreiben würde.



  • > #include <stdio.h>
    > int main(void) {
    > printf("Hello, World!\n"); // oder, besser: puts("Hello, World!");

    }

    fehlt hier nicht ein return 0; ?



  • @groovemaster es ging mir lediglich um die main funktion

    main()
    {
    }
    

    ich wollte nicht sagen das

    #include <cstdio>
    oder 
    printf("bla,bla");
    

    C++ Standard sind!

    OMG!

    @0xdeadbeef

    // oder, besser: puts("Hello, World!");

    puts(); benutzen nur primitive! fputs(,); ist angebrachter!!!

    und das cout und cin C++ ist weis ich auch!

    mfg hohesC 😃

    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
        printf("Das ist ANSI C Standard!\n");
        return(0);
    }
    

    [EDIT]@Vertexwahn ja da fehlt return(0);!!![/EDIT]



  • hohesC schrieb:

    ich wollte nicht sagen das

    #include <cstdio>
    oder 
    printf("bla,bla");
    

    C++ Standard sind!

    Hättest du aber ruhig machen können, denn das ist es durchaus. 😃
    Was ich meinte ist einfach, dass man in einem C-"Hello World!" printf benutzt und in C++ std::cout. Deshalb sieht das Bsp eher nach C als C++ aus.



  • hohesC schrieb:

    #include <cstdio> 
    
    main() 
    { 
    	printf("Hello, World!");
    }
    

    Dieser Code ist illegal.

    Ich weis das für

    printf("");
    

    in C die stdio.h benötigt wird!
    Es ging mir lediglich um den funtionskörper von main.

    Auch das ist nicht ganz richtig. Erst seit C99 ist das nötig.

    hohesC schrieb:

    puts(); benutzen nur primitive! fputs(,); ist angebrachter!!!

    Begründung??

    @Vertexwahn ja da fehlt return(0);!!!

    Nur in C99, in anderen C Standards nicht.



  • Shade Of Mine schrieb:

    hohesC schrieb:

    puts(); benutzen nur primitive! fputs(,); ist angebrachter!!!

    Begründung??

    Vielleicht hat er puts() mit gets() verwechselt 😉



  • Der C99 Standard FCD sagt:

    5.1.2.2.3 Program termination

    [#1] If the return type of the main function is a type
    compatible with int, a return from the initial call to the
    main function is equivalent to calling the exit function
    with the value returned by the main function as its
    argument;9) reaching the } that terminates the main function
    returns a value of 0.
    If the return type is not compatible
    with int, the termination status returned to the host
    environment is unspecified.

    Also nein, da fehlt kein return 0;.


Anmelden zum Antworten