Probleme mit system()



  • Moin!

    Ich teste gerade an Rundungsfehlern und dem Unterschied mit "Optimierungen" in der Ausführungsreihenfolge von LLVM, bzw CLang. Da man die Abarbeitsungsreihenfolge von Operationen bei Forth selbst angibt (mangels Unterstützung mathematischer Ausdrücke), vergleiche ich die Ausgabe mit Forth-Programmen.

    Ich habe hierzu eine For-Schleife im C-Programm , rechne dort mit der Schleifenvariable als Parameter einmal den Originalausdruck und einmal den gleichen Ausdruck manuell optimiert (kleiner und auf Minimierung von Rundungsfehlern -> Eine große Division zum Schluss der Berechnung). Die Ergebnisse gebe ich jeweils nacheinander aus, gefolgt von einem Trennzeichen.

    Jetzt soll das Forth-Programm seine Arbeit verrichten, das Ergebnis der originalen und der optimierten Version ausgeben, eine neue Zeile beginnen und sich beenden, damit im C-Programm der nächste Schleifendurchlauf beginnen kann.

    Irgendwo habe ich jedoch ein Denkfehler drin, denn obwohl alles in einer einzigen Schleife ist, laufen zuerst die Forth-Berechnungen mit allen möglichen Argumenten durch, dann die Berechnungen im C-Programm.

    Der Code des C-Programms:

    #include <stdlib.h>
    #include <stdio.h>
    
    int main(void)
    {
      char buffer[256];
      int k;
      int m;
      for (k = 0; k < 30; k++)
      {
        m = (k * 43 + 1523) / 100;
        printf ("%i ", m);
    
        m = 15 + (3 * k + 3) / 4 - (8 * k + 13) / 25;
        printf ("%i - ", m);
    
        sprintf(buffer, "./test.fs %i", k);
        system(buffer);
      };
      return EXIT_SUCCESS;
    };
    

    Der Code des Forth-Programms "test.fs":

    #! /usr/bin/env gforth
    
    : AusdruckOpt  ( k -- m )
      43 * 1523 + 100 /
    ;
    
    : AusdruckOrig ( k -- m )
      dup 3 * 3 + 4 /     ( k -- k [k*3+3]/4 )
      swap 8 * 13 + 25 /  ( k [k*3+3]/4 -- [k*3+3]/4 [k*8+13]/25 )
      15                  ( [k*3+3]/4 [k*8+13]/25 -- [k*3+3]/4 [k*8+13]/25 15 )    
      rot + swap -
    ;
    
    : main  ( -- )
      next-arg  ( -- addr u )
      s>number?  ( addr u -- x v f )
      if  ( x v f -- x v )
        drop  ( x v -- x )
        dup AusdruckOpt . AusdruckOrig . 
      else
        ." Fehler: Bitte eine Zahl als Argument mitgeben." 2drop  ( x v -- )
      then
    ;
    
    main cr bye
    

    Ausgabe:

    15 15                        
    15 16                        
    16 16                        
    16 17
    16 17
    17 17
    17 18
    18 19
    18 18
    19 19
    19 20
    19 20
    20 20
    20 21
    21 21
    21 22
    22 22
    22 23
    22 23
    23 24
    23 24
    24 24
    24 25
    25 26
    25 25
    25 26
    26 27
    26 27
    27 27
    27 28
    15 15 - 15 16 - 16 16 - 16 17 - 16 17 - 17 17 - 17 18 - 18 19 - 18 18 - 19 19
     - 19 20 - 19 20 - 20 20 - 20 21 - 21 21 - 21 22 - 22 22 - 22 23 - 22 23 - 23
     24 - 23 24 - 24 24 - 24 25 - 25 26 - 25 25 - 25 26 - 26 27 - 26 27 - 27 27 - 
    27 28 -
    

    Gewünschtes Ausgabeformat:

    15 15 - 15 15                        
    15 16 - 15 16                        
    16 16 - 16 16                        
    16 17 - 16 17
    16 17 - 16 17
    17 17 - 17 17
    (...)
    

    Weiß jemand, was ich falsch mache? Forth Implementierung ist gforth, C code ist sowohl mit gcc, als auch mit CLang kompiliert und getestet worden.

    Ehrlich gesagt, habe ich die "system()"-Funktion vorher nie wirklich verwendet, daher weiß ich kaum etwas darüber. Eigentlich sollte es doch das angegebene Kommando ausführen, warten bis es fertig ausgeführt ist, um dann im Programm weiter zu arbeiten. Das macht es ja auch, nur dass sich entweder die Schleife völlig selbständig macht, was ich nicht glaube, oder irgendwie stdout blockiert bleibt, bis alle schleifendurchläufe beendet sind, so dass sich der Ausgabepuffer des C-Programms dann erst nach stdout entleeren kann. Allerdings müsste stdout dann schon vor dem ersten "system()"-Aufruf blockiert sein, was mir sehr seltsam erscheint.



  • Probier als erstes mal hinter dem system ein fflush(stdout) - der leer die Puffer



  • Versuchs mal so:

    #include <stdlib.h>
    #include <stdio.h>
    
    int main(void)
    {
      char buffer[256];
      int k;
      int m;
      for (k = 0; k < 30; k++)
      {
        m = (k * 43 + 1523) / 100;
        printf ("%i ", m);
    
        m = 15 + (3 * k + 3) / 4 - (8 * k + 13) / 25;
        printf ("%i - ", m);
        fflush(stdout);
    
        sprintf(buffer, "echo %i %i", k, k);
        system(buffer);
      } // <--- Klammer sollte weg
      return EXIT_SUCCESS;
    } // <--- Klammer muss weg
    

    🙂

    Edit: Chaos mit den Tags



  • pferdefreund schrieb:

    Probier als erstes mal hinter dem system ein fflush(stdout) - der leer die Puffer

    Das funktioniert. fflush(stdout) muss allerdings vor dem system()-Aufruf durchgeführt werden. Forth spült seinen Kram sonst wohl vor C nach stdout.

    mngbd schrieb:

    Versuchs mal so:

    [...]
    } // <--- Klammer sollte weg
    return EXIT_SUCCESS;
    } // <--- Klammer muss weg
    

    Edit: Chaos mit den Tags

    Verschiedene Sprachen, verschiedene Syntax. Sollte ich mich mal dran gewöhnen. 😃
    Nötig sind die Semikolons da nicht, aber nur zum Interesse: Schadet so eine "leere Anweisung" hinter den Blöcken überhaupt?

    Vielen Dank euch Beiden für die Hinweise!



  • Systempuffer schrieb:

    Nötig sind die Semikolons da nicht, aber nur zum Interesse: Schadet so eine "leere Anweisung" hinter den Blöcken überhaupt?

    Die erste schadet sicher nicht. Bei der zweiten bin ich mir nicht sicher, und mir fällt auch gerade kein Stichwort ein, unter dem ich auf die Schnelle nachschlagen könnte.

    Mein Compiler sagt dazu: Warnung: ISO-C erlaubt kein zusätzliches »;« außerhalb einer Funktion . Manchmal lügt der aber.

    Zumindest innerhalb des Funktionskörpers ist die Faustregel einfach: ein Schlüsselwort wie for verlangt danach eine einzelne anweisung; oder einen {block} von Anweisungen. Wo der Block zu Ende ist, markiert ohnehin schon die Klammer, deshalb muss dort kein Semikolon hin.
    🙂


Anmelden zum Antworten