In C89 zu programmieren...



  • Z schrieb:

    Steffo schrieb:

    ...

    Welche Probleme?

    Umgang mit der Sprache, welche sonst? 😛



  • Zeus schrieb:

    Z schrieb:

    Welche Probleme?

    Umgang mit der Sprache, welche sonst? 😛

    😛

    Problem war hauptsächlich, dass ich eine POSIX-Funktion srandom() mit gcc und den Optionen -ansi -pedantic kompilieren wollte. Ging natürlich nicht, weil das ja kein Standard ist.

    Die Man-Page sagt dazu:

    Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
    
           random(), srandom(), initstate(), setstate():
               _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
    

    Ich hab dann mit der Option -D_XOPEN_SOURCE=600 kompiliert und es hat wunderbar unter Fedora kompiliert.

    Ich gebe also meine Lösung und mein Makefile dem Tutor ab und 1 Woche später sehe ich, dass ich 5% Abzug bekommen habe, weil die C-Datei mit srandom() nicht kompilieren wollte. Ich wollte das zuerst nicht glauben, aber unter Ubuntu an der Hochschule wollte das tatsächlich nicht kompilieren! Die Fehlermeldung war absolut nichtssagend und kryptisch. Jedenfalls ging das dann ohne den Optionen -ansi und -pedantic.

    Aber auch der 89er-Standard an sich nervt mich:

    - Keine statischen Array-Größen per Variablen angebbar, so dass man malloc() benutzen muss --> unsicher und unperformant.

    - Variablen müssen immer am Anfang des Funktionsrumpf definiert werden. Mehrfache Verwendung von abgekapselte Variablen sind so nicht möglich (z. B. in for-Schleifen).

    - Kommentare: // nicht möglich.

    - Kein restrict: Performance-Nachteil

    Diese Dinge stören mich am meisten...

    L. G.
    Steffo



  • Warum hast du nicht einfach srand benutzt?

    Was for-Schleifen angeht, so kann man das Scope-Verhalten von C99 nachbauen, wenngleich das dann nicht sonderlich hübsch aussieht:

    {
      int i;
      for(i = 0; i < 10; ++i) {
        ...
      }
    }
    

    Ansonsten kannst du in deine Makefile natürlich statt -ansi auch -std=c99 schreiben, obwohl srandom auch in C99 nicht enthalten ist.

    Wenn du aber wirklich mal Produktionscode in C schreiben musst, wird der Umstand, dass Microsoft sich nicht um die Erfüllung des C99-Standards schert, auf absehbare Zeit an C89 ketten (es sei denn, Portabilität spielt überhaupt keine Rolle). Das muss man nicht mögen, aber Drohbriefe brächten wahrscheinlich auch nichts.



  • Steffo schrieb:

    Zeus schrieb:

    Z schrieb:

    Welche Probleme?

    Umgang mit der Sprache, welche sonst? 😛

    😛

    Problem war hauptsächlich, dass ich eine POSIX-Funktion srandom() mit gcc und den Optionen -ansi -pedantic kompilieren wollte. Ging natürlich nicht, weil das ja kein Standard ist.

    Die Man-Page sagt dazu:

    Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
    
           random(), srandom(), initstate(), setstate():
               _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
    

    Ich hab dann mit der Option -D_XOPEN_SOURCE=600 kompiliert und es hat wunderbar unter Fedora kompiliert.

    Ich gebe also meine Lösung und mein Makefile dem Tutor ab und 1 Woche später sehe ich, dass ich 5% Abzug bekommen habe, weil die C-Datei mit srandom() nicht kompilieren wollte. Ich wollte das zuerst nicht glauben, aber unter Ubuntu an der Hochschule wollte das tatsächlich nicht kompilieren! Die Fehlermeldung war absolut nichtssagend und kryptisch. Jedenfalls ging das dann ohne den Optionen -ansi und -pedantic.

    Aber auch der 89er-Standard an sich nervt mich:

    - Keine statischen Array-Größen per Variablen angebbar, so dass man malloc() benutzen muss --> unsicher und unperformant.

    - Variablen müssen immer am Anfang des Funktionsrumpf definiert werden. Mehrfache Verwendung von abgekapselte Variablen sind so nicht möglich (z. B. in for-Schleifen).

    - Kommentare: // nicht möglich.

    - Kein restrict: Performance-Nachteil

    Diese Dinge stören mich am meisten...

    L. G.
    Steffo

    - Nimm einfach rand() und srand(). Das geht immer und dann brauchst du auch nicht mit irgendwelchen komischen Compiler-Options herumzufummeln.

    - Auch in C89 kannst du schleifenlokale Variablen anlegen (direkt nach der öffnenden, geschweiften Klammer).

    - C ist eine Art portable Assemblersprache, deshalb finde ich Automatismen, die sich hinter VLAs verbergen, eher unpassend. Ich finde, wer auf VLAs angewiesen ist, macht etwas falsch.

    - Der Rest wird von dir überbewertet. Restricted Pointers z.B. sind ein nettes Feature um dem Compiler zu helfen, aber nicht wirklich lebensnotwendig.



  • war ansi nicht c90? In c89 sollte es auch kein const geben.

    Variablen müssen immer am Anfang des Funktionsrumpf definiert werden. Mehrfache Verwendung von abgekapselte Variablen sind so nicht möglich (z. B. in for-Schleifen)

    wohl eher am Anfang eines Blocks.



  • Z schrieb:

    - Nimm einfach rand() und srand(). Das geht immer und dann brauchst du auch nicht mit irgendwelchen komischen Compiler-Options herumzufummeln.

    Wir benutzen ziemlich oft POSIX-Schnittstellen. Der C-Standard wird nicht alles abdecken können...

    - Auch in C89 kannst du schleifenlokale Variablen anlegen (direkt nach der öffnenden, geschweiften Klammer).

    Sieht halt dann entsprechend aus...

    - C ist eine Art portable Assemblersprache, deshalb finde ich Automatismen, die sich hinter VLAs verbergen, eher unpassend. Ich finde, wer auf VLAs angewiesen ist, macht etwas falsch.

    VLAs sind sehr praktisch: Man braucht keinen Malloc-Funktionsaufruf, die Ausnahmebehandlung entfällt, das free() und der Gedanke, wann man Speicher wieder frei gibt, ebenso.

    Versuch mal beim Minix-Kernel einen malloc() zu finden!
    Hier siehst du einen Patch, der einen malloc() durch ein VLA ersetzt:

    http://git.minix3.org/?p=minix.git;a=commitdiff;h=f0f34dd8d9dc89a607730dbc697bd505c2773182

    So etwas ist einfach nicht gerne gesehen...

    Stell dir vor, du macht am Anfang des Funktionsrumpfes ein malloc() und am Ende ein free(). Nach dem malloc() kommen jedoch verschiedene switch cases und eins davon macht ein return... Glückwunsch: Du hast ein Memory Leak.
    Ich weiß... so etwas passiert DIR natürlich nicht...

    Tanenbaum ist sich selbst gegenüber kritisch genug, um mallocs zu vermeiden wo es nur geht. Im Kernel selbst kommt kein einziges malloc() vor. In einigen Treiber können sie vereinzelt vorkommen.

    - Der Rest wird von dir überbewertet. Restricted Pointers z.B. sind ein nettes Feature um dem Compiler zu helfen, aber nicht wirklich lebensnotwendig.

    Man kann damit verdammt gut optimieren...

    L. G.
    Steffo



  • Steffo schrieb:

    VLAs sind sehr praktisch

    Nein, VLAs sind schrecklich. Also wirklich, absolut schrecklich. Das Grauen auf Erden. Wenn die Menschheit ausstirbt, dann wegen VLAs!
    Was aber wirklich nett wäre, wäre ein alloca Äquivalent im Standard.

    Und ja, C hat definitiv ein Problem was Resource-Management angeht. Und ja, du hast recht. Warum sollte man in C Programmieren? Es gibt aus sprachlicher Sicht eigentlich keine Gründe dafür. Selbst wenn man keine Exceptions und keine Polymorphie will, Destruktoren sind etwas, das C einfach fehlt. (Obwohl es natürlich nicht zur Sprache passen würde.)

    Allerdings stellt sich die Frage, was du mit diesem Thread bezwecken willst. Die meisten User hier werden wohl C++ bevorzugen, und niemand hier wird den Lehrplan deiner Uni ändern können. Wenn du diese Diskussion führen willst, dann bitte gleich mit dem MOC (Master Of C) persönlich: Linus. 😉



  • cooky451 schrieb:

    Und ja, C hat definitiv ein Problem was Resource-Management angeht. Und ja, du hast recht. Warum sollte man in C Programmieren? Es gibt aus sprachlicher Sicht eigentlich keine Gründe dafür. Selbst wenn man keine Exceptions und keine Polymorphie will, Destruktoren sind etwas, das C einfach fehlt. (Obwohl es natürlich nicht zur Sprache passen würde.)

    Allerdings stellt sich die Frage, was du mit diesem Thread bezwecken willst. Die meisten User hier werden wohl C++ bevorzugen, und niemand hier wird den Lehrplan deiner Uni ändern können. Wenn du diese Diskussion führen willst, dann bitte gleich mit dem MOC (Master Of C) persönlich: Linus. 😉

    Der Blödmann ist gegen C++, weil man damit viel leichter Scheiße produzieren kann. C++ ist "in", jeder Vollidiot kopiert sich aus dem Internet etwas zusammen. C ist für Anfänger eher unattraktiv, weil man Hintergrundwissen benötigt, um die Sprachkonzepte zu verstehen und sinnvoll anzuwenden.
    C++ hat eine lange Entwicklung von C mit Klassen zu C++11 erlebt. Compiler kommen langsam hinterher, Literatur wird nicht jünger und die Nähe zu C verleitet zu scheußlichen Hacks. C++ ist also ein großes Durcheinander und nur erfahrene Programmierer können damit guten Code bauen, weil sie schon viele Fehler kennen, die man machen kann.
    C ist viel schlanker, es gibt nicht zig Möglichkeiten, etwas zu lösen. Zum Beispiel gibt es keine Methoden, Lambdas, Konstruktoren, überladbare Operatoren, sondern einfach nur Funktionen, die man nicht einmal überladen kann. C hat sich auch nicht stark verändert. Aus Kompatibilitätsgründen verwendet man meist C89 und gut ist.
    C++ ist als Sprache überlegen, aber das ist in der Praxis nicht das einzige Kriterium. Bei Linux reicht C eben aus und man vermeidet die Probleme von C++.



  • Steffo schrieb:

    Hier siehst du einen Patch, der einen malloc() durch ein VLA ersetzt:

    http://git.minix3.org/?p=minix.git;a=commitdiff;h=f0f34dd8d9dc89a607730dbc697bd505c2773182

    Ich sehe da kein VLA.



  • Kenner der Wichtigtuer schrieb:

    Steffo schrieb:

    Hier siehst du einen Patch, der einen malloc() durch ein VLA ersetzt:

    http://git.minix3.org/?p=minix.git;a=commitdiff;h=f0f34dd8d9dc89a607730dbc697bd505c2773182

    Ich sehe da kein VLA.

    OK, ich nehme alles zurück und behaupte das Gegenteil. 🙂



  • Man muss mit VLAs tatsächlich vorsichtig umgehen:

    One problem that may be hidden by a language's support for VLAs is that of the underlying memory allocation: in environments where there is a clear distinction between a heap and a stack, it may not be clear which, if any, of those will store the VLA.
    
    For example, the GNU C Compiler allocates memory for VLAs on the stack. If a VLA is too large, no error occurs immediately; instead, attempts to use the VLA may lead to segmentation faults later in the execution of the program.
    

    http://en.wikipedia.org/wiki/Variable-length_array



  • Dieses spezielle Problem besteht allerdings auch bei Arrays fester Länge.



  • Allerdings kannst du das dann besser kontrollieren, weil dir die Größe bekannt ist.



  • Wie denn?



  • Wenn ich weiß, ich brauch einen Puffer von 1 MB, dann würde ich nicht auf die Idee kommen den Puffer auf dem Stack zu alloziieren. 😛



  • Und wenn du einen Puffer von 128 Bytes brauchst? Woher weißt du dann, ob der Stack ausreicht?

    Rhetorische Frage, kürzen wirs ab: Du weißt es nicht.



  • VLAs sind sehr praktisch: Man braucht keinen Malloc-Funktionsaufruf, die Ausnahmebehandlung entfällt, das free() und der Gedanke, wann man Speicher wieder frei gibt, ebenso.

    Benutze bitte keine Messer, du koenntest dich sehr oft schneiden. Nimm bitte Java und ueberlasse C den echten Programmierern.

    Stell dir vor, du macht am Anfang des Funktionsrumpfes ein malloc() und am Ende ein free(). Nach dem malloc() kommen jedoch verschiedene switch cases und eins davon macht ein return... Glückwunsch: Du hast ein Memory Leak.
    Ich weiß... so etwas passiert DIR natürlich nicht...

    Genau. Auch gibt es "Lint"-Tools, die das ueberpruefen. Und nochmal: Bitte benutze kein Messer.

    Das musste mal gesagt werden! Ach ja, ich distanziere mich sofort wieder davon.



  • @knivil: Sorry, aber was ist das für ein idiotischer Beitrag?
    Die, die sich für echte Programmierer halten, sind meist die, die ziemlich unsichere, unwartbare Bananensoftware schreiben.
    VLAs sind auch nicht sicher, das sehe ich jetzt, aber hat nicht jeder mal klein angefangen und aus Fehlern gelernt? 🙄



  • Steffo schrieb:

    @knivil: Sorry, aber was ist das für ein idiotischer Beitrag?

    knivil kann nicht anders. Was ist mit dir, wieso musst du darauf antworten?



  • cooky451 schrieb:

    Und ja, C hat definitiv ein Problem was Resource-Management angeht.

    Nein, C hat gar kein eingebautes Ressource Management. Das ist kein "Problem", das ist so gewollt.

    cooky451 schrieb:

    Und ja, du hast recht. Warum sollte man in C Programmieren? Es gibt aus sprachlicher Sicht eigentlich keine Gründe dafür.

    Einen standardkonformen C-Code kannst du für fast jeden Prozessor compilieren lassen und er verhält sich überall gleich. Insbesondere dann, wenn du keine Library-Funktionen zum Speichermanagement benötigst. Keine andere Sprache leistet das.


Anmelden zum Antworten