Array Inhalte miteinander Multiplizieren.



  • @DirkB sagte in Array Inhalte miteinander Multiplizieren.:

    @Tyrdal sagte in Array Inhalte miteinander Multiplizieren.:

    @wob sagte in Array Inhalte miteinander Multiplizieren.:

    @Tyrdal sagte in Array Inhalte miteinander Multiplizieren.:

    Also Länge größer 0 aber mit nullptr empfinde ich als ungültig.

    Ok, das ist klar! Aber das sollte UB sein.

    Also gerade das häufige UB macht C++ ja so unhandlichund unsicher. Ich weiß nicht ob man da selber noch mit dazu beitragen sollte.

    Sorge beim Aufruf dafür, dass es kein UB gibt.
    Evtl. mit einer eigenen Funktion product_s()

    Na genau daran scheitert es ja so häufig. Die Leute tun das nicht.



  • @Tyrdal sagte in Array Inhalte miteinander Multiplizieren.:

    Sorge beim Aufruf dafür, dass es kein UB gibt.
    Evtl. mit einer eigenen Funktion product_s()

    Na genau daran scheitert es ja so häufig. Die Leute tun das nicht.

    Für mich wäre jetzt die Frage interessant was mit solchen Leuten zu besseren Ergebnissen führt. a) auf bestimmte falsche Eingaben zu prüfen und den Fehler irgendwie "graceful" zu behandeln oder b) genau das eben ganz absichtlich nicht zu tun, in der Hoffnung dass die Leute dadurch lernen besser aufzupassen.

    Und mMn. ist für C bzw. C++ (b) nicht unbedingt verkehrt. Wobei man die Checks ruhig einbauen kann. Nur solche Fehlerfälle "graceful" zu behandeln finde ich verkehrt. Wenn dann das Programm abbrechen. Weil es einerseits die einzig "sichere" Option ist (kein Ergebnis ist meistens besser als ein falsches Ergebnis/unkontrollierter Crash/...), und andrerseits zwingt man die Benutzer der Funktion dadurch besser aufzupassen.



  • @hustbaer sagte in Array Inhalte miteinander Multiplizieren.:

    @Tyrdal sagte in Array Inhalte miteinander Multiplizieren.:

    Sorge beim Aufruf dafür, dass es kein UB gibt.
    Evtl. mit einer eigenen Funktion product_s()

    Na genau daran scheitert es ja so häufig. Die Leute tun das nicht.

    Für mich wäre jetzt die Frage interessant was mit solchen Leuten zu besseren Ergebnissen führt. a) auf bestimmte falsche Eingaben zu prüfen und den Fehler irgendwie "graceful" zu behandeln oder b) genau das eben ganz absichtlich nicht zu tun, in der Hoffnung dass die Leute dadurch lernen besser aufzupassen.

    Und mMn. ist für C bzw. C++ (b) nicht unbedingt verkehrt. Wobei man die Checks ruhig einbauen kann. Nur solche Fehlerfälle "graceful" zu behandeln finde ich verkehrt. Wenn dann das Programm abbrechen. Weil es einerseits die einzig "sichere" Option ist (kein Ergebnis ist meistens besser als ein falsches Ergebnis/unkontrollierter Crash/...), und andrerseits zwingt man die Benutzer der Funktion dadurch besser aufzupassen.

    Wenn ich mir die Sicherheitslücken anschaue ist Ansatz b) grandios gescheitert. Selbst talentierte Entwickler hauen da manchmal daneben. Die meisten legen aber eh keine besondere Sorgfalt an den Tag. Ist zumindest meine Erfahrung.

    Und wegen dem "Crash" scglug ich ja asserts vor. Ist quasi der Mittelweg zwischen a und b.



  • @hustbaer sagte in Array Inhalte miteinander Multiplizieren.:

    Für mich wäre jetzt die Frage interessant was mit solchen Leuten zu besseren Ergebnissen führt. a) auf bestimmte falsche Eingaben zu prüfen und den Fehler irgendwie "graceful" zu behandeln oder b) genau das eben ganz absichtlich nicht zu tun, in der Hoffnung dass die Leute dadurch lernen besser aufzupassen.

    Die Erfahrung mit C (und auch C++) zeigt – gar nicht. Die endlosen Serie an Exploits von C artigen Libraries und Applikationen zeigt, dass das nie funktionieren wird. Das Problem ist hier, dass das Feld und der rohe Zeiger nicht als Einheit übergeben wird, sondern als zwei Variablen. Hinzu kommt, dass man in C leicht jeden beliebigen Zeiger sogar jeden ausreichend großen Integerwert in einen „passenden“ Zeiger konvertieren kann, wenn man die C Casts nutzt.

    Mir graut es vor so etwas

    #include <math.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    float product(float *data, size_t length) {
        if (length == 0) return 1.0f;
        if (length >= 1 && !data) return NAN; 
    
        float r = 1.0f;
    
        for (size_t i = 0; i < length; ++i) r *= data[i];
    
        return r;
    }
    
    int main() {
        float p = 0.0f;
        char string[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    
        p = product ((float*)string, 4);
        printf("%f\n", p);
    }
    
    


  • Wenn ich mir die Sicherheitslücken anschaue ist Ansatz b) grandios gescheitert.

    Die typischen Sicherheitslücken kannst du mit Parameter-Checks in C bloss leider nicht abfangen. Prüfen kannst du Nullpointer + Grösse > 0. Das ist aber kaum jemals ne Sicherheitslücke. Das crasht einfach mit nem SIGSEGV weg ohne dass vorher schlimme Dinge passieren.

    Ein assert hilft da maximal dass man schneller & ohne Dump sieht wo der Fehler passiert ist. (Wobei man auch nur die aufgerufene Funktion sieht, was oft gar nicht so viel bringt.)

    Interessant wären so Sachen wie non-null Zeiger + falsche Grösse. Oder generell out-of-bounds Zugriffe. Nur genau das kannste in C halt nicht prüfen.

    In C++ geht schon etwas mehr. Aber auch nur wenn man so "Zeiger + Grösse" APIs wie diese hier komplett vermeidet.



  • @hustbaer sagte in Array Inhalte miteinander Multiplizieren.:

    Wenn ich mir die Sicherheitslücken anschaue ist Ansatz b) grandios gescheitert.

    Die typischen Sicherheitslücken kannst du mit Parameter-Checks in C bloss leider nicht abfangen. Prüfen kannst du Nullpointer + Grösse > 0. Das ist aber kaum jemals ne Sicherheitslücke. Das crasht einfach mit nem SIGSEGV weg ohne dass vorher schlimme Dinge passieren.

    Ein assert hilft da maximal dass man schneller & ohne Dump sieht wo der Fehler passiert ist. (Wobei man auch nur die aufgerufene Funktion sieht, was oft gar nicht so viel bringt.)

    Wieso ohne dump? Klar kann ich einen core dump von nem assert bekommen.



  • @hustbaer sagte in Array Inhalte miteinander Multiplizieren.:

    Für mich wäre jetzt die Frage interessant was mit solchen Leuten zu besseren Ergebnissen führt. a) auf bestimmte falsche Eingaben zu prüfen und den Fehler irgendwie "graceful" zu behandeln oder b) genau das eben ganz absichtlich nicht zu tun, in der Hoffnung dass die Leute dadurch lernen besser aufzupassen.

    oder c.) bei jeder möglichen falschen Eingabe eine Exception zu werfen (z.B. FormatException), wie dies in .Net der Fall zu sein scheint.

    Ich bekomme da ein wenig das Gefühl einer Erziehungsmaßname.



  • @Tyrdal sagte in Array Inhalte miteinander Multiplizieren.:

    Ein assert hilft da maximal dass man schneller & ohne Dump sieht wo der Fehler passiert ist. (Wobei man auch nur die aufgerufene Funktion sieht, was oft gar nicht so viel bringt.)

    Wieso ohne dump? Klar kann ich einen core dump von nem assert bekommen.

    Stell dir vor dass vor "ohne Dump" ein "auch" steht. Besser?



  • @Quiche-Lorraine sagte in Array Inhalte miteinander Multiplizieren.:

    oder c.) bei jeder möglichen falschen Eingabe eine Exception zu werfen (z.B. FormatException), wie dies in .Net der Fall zu sein scheint.

    Ich bin wohl einer der wenigen die bemerkt haben dass wir hier im C (ohne ++) Bereich sind.

    Davon abgesehen sind Exceptions auch so ne Sache. Richtig eingesetzt sind die schon fein. Aber wenn man mit Exceptions arbeitet, speziell so dass bei jedem Scheiss gleich eine geworfen wird, dann ergeben sich sehr viele "unsichtbare" Fehler-Pfade. Und die meisten Programmierer die ich kenne achten da nicht besonders gut darauf. Da finde ich oft Code der sich falsch verhalten würde wenn an einer bestimmten Stelle z.B. ein bad_alloc fliegt (meist Leaks, aber manchmal auch schlimmeres).



  • @hustbaer sagte in Array Inhalte miteinander Multiplizieren.:

    @Tyrdal sagte in Array Inhalte miteinander Multiplizieren.:

    Ein assert hilft da maximal dass man schneller & ohne Dump sieht wo der Fehler passiert ist. (Wobei man auch nur die aufgerufene Funktion sieht, was oft gar nicht so viel bringt.)

    Wieso ohne dump? Klar kann ich einen core dump von nem assert bekommen.

    Stell dir vor dass vor "ohne Dump" ein "auch" steht. Besser?

    Ja, besser :). Wobei mir der callstack meistens schon hilft.



  • @hustbaer sagte in Array Inhalte miteinander Multiplizieren.:

    Ich bin wohl einer der wenigen die bemerkt haben dass wir hier im C (ohne ++) Bereich sind.

    Man kann auch in C Exceptions implementieren 🤓



  • @hustbaer sagte in Array Inhalte miteinander Multiplizieren.:

    Da finde ich oft Code der sich falsch verhalten würde wenn an einer bestimmten Stelle z.B. ein bad_alloc fliegt (meist Leaks, aber manchmal auch schlimmeres).

    In Zeiten des massiven Memory Overcommitments ist es nahezu unmöglich noch in irgend einer Form sinnvoll das ganze zu behandeln. Das OS wird bei normalen Speicheranforderungen i.d.R. nie ein bad_alloc werfen, sondern erst bei einem Zugriff auf den allozierten Speicher feststellen, dass nicht ausreichend Speicher vorhanden ist. Linux kickt dann nach einem speziellen Algorithmus (kann man auch konfigurieren) irgend ein Programm raus. Es muss nicht das Programm sein, dass zuviel Speicher angefordert hat.



  • @Tyrdal sagte in Array Inhalte miteinander Multiplizieren.:

    @hustbaer sagte in Array Inhalte miteinander Multiplizieren.:

    @Tyrdal sagte in Array Inhalte miteinander Multiplizieren.:

    Ein assert hilft da maximal dass man schneller & ohne Dump sieht wo der Fehler passiert ist. (Wobei man auch nur die aufgerufene Funktion sieht, was oft gar nicht so viel bringt.)

    Wieso ohne dump? Klar kann ich einen core dump von nem assert bekommen.

    Stell dir vor dass vor "ohne Dump" ein "auch" steht. Besser?

    Ja, besser :). Wobei mir der callstack meistens schon hilft.

    Was ich meinte ist: ein assert hat den (kleinen) Vorteil dass man auch ohne einen Dump zu ziehen ein bisschen was an Info rausbekommt. Das kann hilfreich sein in Fällen wo man aus irgendeinem Grund keinen Dump bekommen kann.


Anmelden zum Antworten