Funktionen welche man nicht verwenden sollte



  • Hallo welche Funktionen in C++ sollte man nicht verwenden da diese unsicher sind ?

    In C weiss ich z.b. das man diese Funktionen vermeiden sollte in Anwendungen wo es auf Sicherheits ankommt:

    gets();
    strcpy();

    Aber welche Funktionen sind es in C++ welche man vermeiden sollte ?



  • goto ist schlechter Stil



  • func schrieb:

    Aber welche Funktionen sind es in C++ welche man vermeiden sollte ?

    C 🙂



  • Eieiei, da kommt mit Sicherheit von den ganzen C++-Puristen hier die typische Anwort: "alle Funktionen, die es auch in C gibt, sind böse!" 😃

    Bedenke, dass es für unsichere Funktionen wie strcpy oder sprintf auch sichere Varianten wie strncpy oder snprintf/_snprintf gibt. Und auch ein ach so böses sprintf ist eigentlich harmlos, wenn du im Formatstring nicht %s verwendest (so dass es zu Überläufen kommen kann).



  • ligginator schrieb:

    goto ist schlechter Stil

    goto ist vor allem keine Funktion. 🕶



  • func schrieb:

    In C weiss ich z.b. das man diese Funktionen vermeiden sollte in Anwendungen wo es auf Sicherheits ankommt:

    gets();
    strcpy();

    Du solltest wissen, warum diese Funktionen unsicher sind (und im Falle von strcpy wann und wann nicht). Dann erübrigt sich die Frage auch in C++ vollständig.



  • Unsicher sind die C-Funktionen nur, wenn du dich nicht damit auskennst. Aber, selbst wenn man 90% kennt, kann man Fehler in Massen begehen. Auch bei guter Kenntnis muss man dauernd aufpassen wegen Flüchtigkeitsfehlern, Refactoring und solchen Sachen. Ich mag an vielen C++-Konstrukten, dass man sich ein bisschen mehr auf die eigentliche Programmlogik konzentrieren kann und die Gefahr von undefiniertem Verhalten ziemlich eingeschränkt wird.



  • _matze schrieb:

    Bedenke, dass es für unsichere Funktionen wie strcpy oder sprintf auch sichere Varianten wie strncpy oder snprintf/_snprintf gibt. Und auch ein ach so böses sprintf ist eigentlich harmlos, wenn du im Formatstring nicht %s verwendest (so dass es zu Überläufen kommen kann).

    strncpy ist nicht wirklich sicher und dazu noch eine ziemlich unpraktische Funktion. Also strncpy sollte man nicht benutzen. (Ich frag mich immer, wer sich so einen Schwachsinn wie strncpy ausgedacht hat).

    snprintf gibt es in C++ nicht und bei sprintf kann es auch zu überläufen kommen, wenn man %s nicht verwendet. (zumal ich zu Boost.Format raten würde, dann spart man sich eh die ganzen %Typ-frickeleien)



  • rüdiger schrieb:

    (Ich frag mich immer, wer sich so einen Schwachsinn wie strncpy ausgedacht hat).

    Wieso? Es ist halt ein memcpy für char-Arrays (mit Nullterminierung als Begrenzer) und für genau diesen Fall doch recht praktisch. Was würdest du (in C) stattdessen benutzen?

    rüdiger schrieb:

    snprintf gibt es in C++ nicht

    Ok. Der MS-Compiler bietet _snprintf und sprintf_s.

    rüdiger schrieb:

    bei sprintf kann es auch zu überläufen kommen, wenn man %s nicht verwendet.

    Du meinst, wenn der Ergebnis-String nicht ins Ziel passt (was anderes fällt mir nicht ein)? Das wäre dann so der Fall, wo ich sagen würde: selber schuld! 😉 Du magst da recht haben, die Möglichkeit besteht, aber das ist dann eindeutig ein böser Fehler des Programmierers.



  • _matze schrieb:

    Du magst da recht haben, die Möglichkeit besteht, aber das ist dann eindeutig ein böser Fehler des Programmierers.

    Darum ging es jz ja gar nicht - es kann halt einfach mal passieren - und es ist ein Fehler, der extrem schwer zu finden ist...
    Mir fällt auf die schnelle keine C++ - Funktion ein, die ähnlich schwer zu findende Fehler verursachen würde...

    bb



  • Noch was:

    _matze schrieb:

    Eieiei, da kommt mit Sicherheit von den ganzen C++-Puristen hier die typische Anwort: "alle Funktionen, die es auch in C gibt, sind böse!" 😃

    Nein, wer sowas sagt, hat schlicht keine Ahnung. Aber ich habe manchmal den Eindruck, du übersiehst ein wenig die Gefährlichkeit der C-Funktionen - vielleicht, weil du selbst schon sehr geübt mit ihnen bist. Aber auch dir passieren sicher ab und zu Fehler, wenn auch wenige. Während z.B. bei den Formatstring-Funktionen ein falsches %-Flag zu undefiniertem Verhalten führt, erhält man bei den Streamoperatoren Compilerfehler bei inkorrekten Typen. Solche Fehler sind viel leichter zu beheben; ähnliche Beispiele findet man viele.

    Wenn man schon C++ programmiert, halte ich es für besser, im Allgemeinen die gegebenen Möglichkeiten zu nutzen als auf Funktionen wie _snprintf() zurückzugreifen, welche die Probleme der ursprünglichen C-Funktionen nur teilweise beheben und nicht einmal im Standard enthalten sind. Es muss ja nicht immer so sein, aber in vielen Fällen hat man nur Vorteile durch die C++-Alternativen (bzw. eventuelle Nachteile kann man gut verkraften).



  • func schrieb:

    Hallo welche Funktionen in C++ sollte man nicht verwenden da diese unsicher sind ?

    wenn man sich nur dumm genug anstellt, kann jede Funktion unsicher sein



  • rüdiger schrieb:

    _matze schrieb:

    Bedenke, dass es für unsichere Funktionen wie strcpy oder sprintf auch sichere Varianten wie strncpy oder snprintf/_snprintf gibt. Und auch ein ach so böses sprintf ist eigentlich harmlos, wenn du im Formatstring nicht %s verwendest (so dass es zu Überläufen kommen kann).

    strncpy ist nicht wirklich sicher und dazu noch eine ziemlich unpraktische Funktion. Also strncpy sollte man nicht benutzen. (Ich frag mich immer, wer sich so einen Schwachsinn wie strncpy ausgedacht hat).

    Ach wie ich gebashe ohne Argumentation liebe 🙄



  • _matze schrieb:

    rüdiger schrieb:

    (Ich frag mich immer, wer sich so einen Schwachsinn wie strncpy ausgedacht hat).

    Wieso? Es ist halt ein memcpy für char-Arrays (mit Nullterminierung als Begrenzer) und für genau diesen Fall doch recht praktisch. Was würdest du (in C) stattdessen benutzen?

    Schauen wir mal in der Doku von man: strncpy nach:

    manpage schrieb:

    The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed
    in dest will not be null terminated.

    Sprich: In den meisten Fällen macht strncpy zu viele oder im schlimmsten Fall sogar zu wenig 0en am Ende.

    Ich würde dann wohl eher wie OpenBSDs strlcpy oder MSs strcpy_s oder was ähnliches basteln/benutzen. Aber vermutlich würde ich mir ohnehin eher eigene Strings basteln, wenn ich viel mit Strings in C rumspielen müsste.

    _matze schrieb:

    rüdiger schrieb:

    bei sprintf kann es auch zu überläufen kommen, wenn man %s nicht verwendet.

    Du meinst, wenn der Ergebnis-String nicht ins Ziel passt (was anderes fällt mir nicht ein)? Das wäre dann so der Fall, wo ich sagen würde: selber schuld! 😉 Du magst da recht haben, die Möglichkeit besteht, aber das ist dann eindeutig ein böser Fehler des Programmierers.

    Ich denke bei sprintf passieren schneller Fehler als man glaubt. Ein Beispiel was mir spontan einfällt wäre

    int x = ...;
    if(x <= 100) {
      char foo[4];
      sprintf(foo, "%d", x);
      puts(foo);
    }
    


  • rüdiger schrieb:

    int x = ...;
    if(x <= 100) {
      char foo[4];
      sprintf(foo, "%d", x);
      puts(foo);
    }
    

    Du meinst z.B. für x=-12345, ja? Klar, da hat dann einer nicht nachgedacht und ist selbst schuld. Aber gut, sowas kann mit char-Arrays und sprintf passieren, und mit std::string, CString usw. ist es definitiv schwieriger (wenn auch nicht unmöglich), Quatsch zu machen. Da habt ihr schon Recht. Was ich nur sagen will ist, dass man auch mit sprintf und Konsorten komplett fehlerfreien 1A-Code schreiben kann. Und dass das gar nicht so schwer ist, wenn man auf ein paar wenige Dinge achtet.

    Und zum Thema "sprintf-Fehler sind extrem schwer zu finden": ich kann mit einer Meldung "The Stack around 'foo' was corrupted" (so sie denn kommt 😉 ) eindeutig mehr anfangen, als mit einer 10-seitigen Aneinanderreihung von Template-Fehlermeldungen. 😃



  • _matze schrieb:

    ...
    Und zum Thema "sprintf-Fehler sind extrem schwer zu finden": ich kann mit einer Meldung "The Stack around 'foo' was corrupted" (so sie denn kommt 😉 ) eindeutig mehr anfangen, als mit einer 10-seitigen Aneinanderreihung von Template-Fehlermeldungen. 😃

    Aber nicht, wenn Erstere 2000 Enduser im ersten halben Jahr nach Auslieferung zu sehen bekommen, Zweitere aber der Entwickler nach dem Compile .... :p 😉

    Gruß,

    Simon2.


  • Administrator

    Simon2 schrieb:

    Aber nicht, wenn Erstere 2000 Enduser im ersten halben Jahr nach Auslieferung zu sehen bekommen, ...

    Möchte ich noch etwas ergänzen:
    Und wenn diese 2000 Enduser dann durch den Absturz alle Daten verlieren, weil sie nicht mehr speichern konnten und deinen Support nur gehässigt zuspammen, statt den Fehler zu melden :p

    @_matze,
    Ich glaube es hat hier nie jemand dem widersprochen, dass man damit nicht auch 1A Code schreiben kann. Es ging nur darum, wie man auf die Fehler reagieren kann und was fehleranfälliger ist. Ich ziehe jedenfalls Kompilerfehler eindeutig einem Laufzeitfehler vor 😉
    Und mit ein wenig Übung kannst du ohne Probleme auch ellenlange Templatefehlermeldungen verstehen. Das meiste kann man nämlich ignorieren 🙂

    Grüssli


Anmelden zum Antworten