Mischung von C und C++ unterdrücken



  • Gibt es keine Möglichkeit sich in C++-Projekte warnen zu lassen, wenn irgendwo unsichere Funktionen der C-StdLib genutzt werden, oder wenn mit nacktem Pointer-Fu rumgespielt wird? Menschen machen garantiert Fehler, das kann man nicht wegdiskutieren. Zu der Frage hat mich der Ausschnitt des Wikipedia-Artikels zu BufferOverflows gebracht, in dem irgendwie C und C++ teilweise in einem Topf geworfen wird, was ja auch stimmt, da C eine Teilmenge von C++ ist.

    Gibt es eine Möglichkeit diese Kompatibilität zu C zum Teil aufzubrechen, also z.B. dass den C++-StdLibs alles erlaubt ist, nur bei selbst geschriebenen Sachen läuten dann die Alarmglocken? So ähnlich wie bei der CPU, wo Ring0 alles darf, die anderen aber nicht.

    .
    .
    .
    Die häufig verwendete Programmiersprache C++ bietet nur eingeschränkte Möglichkeiten zur automatischen Überprüfung von Feldgrenzen. Als Weiterentwicklung der Programmiersprache C übernimmt sie sämtliche Eigenschaften von C, wobei sich aber das Risiko von Pufferüberläufen bei Benutzung von modernen Sprachmitteln (u. a. automatische Speicherverwaltung) weitestgehend vermeiden lässt. Aus Gewohnheit, Kompatibilitätsgründen zu vorhandenem C-Code, Systemaufrufen in C-Konvention sowie aus Performancegründen wird von diesen Möglichkeiten aber nicht immer Gebrauch gemacht. Laufzeitüberprüfungen sind im Gegensatz zu Sprachen wie beispielsweise Pascal oder Ada nicht Bestandteil der Sprache, lassen sich aber in einigen Anwendungsfällen (z. B. mit Smart Pointern) nachrüsten.

    Da die meisten Programmiersprachen auch Standardbibliotheken definieren, bedeutet die Wahl einer Sprache meist auch die Verwendung der entsprechenden Standardbibliotheken. Im Fall von C und C++ enthält die Standardbibliothek eine Anzahl von gefährlichen Funktionen, die zum Teil gar keine sichere Verwendung zulassen und zu denen zum Teil keine Alternativen bestehen.
    .
    .
    .

    Quelle:http://de.wikipedia.org/wiki/Puffer%C3%BCberlauf



  • Soweit ich weiß nicht, aber es gibt Profiler, die Bufferoverlows und vieles mehr erkennen. clang kann das z. B. und valgrind zum Teil auch, aber nur auf dem Heap.

    Was es gibt, ist clang modernize. Der portiert praktisch automatisch alten C++ Code in modernes C++. Wie gut das funktioniert, kann ich allerdings nicht aus der Praxis sagen. Ich habe nur eine Präsentation dazu gesehen.

    L. G.,
    IBV



  • Ja danke, das Video von Google Native kenne ich auch, falls du das meinst(The Care and Feeding of C++'s Dragons). Ich denke Clang wird die C++-Entwicklung um einiges besser und sicherer machen. Ich dachte nur, es gibt vielleicht direkt einen Compilerschalter oder sonst ein IDE-Feature, was vor unsicherem C-Zeugs warnt. C-Zeugs ist aber auch ein sehr schwammiger Begriff. Ich denke Clang mit seinen Tools geht da schon in die richtige Richtung.



  • gcc hat eine Menge Warnungen, ich glaube aber nur begrenzt hierfuer.
    VC will einem immer sichere, aber dafuer unportable Alternativen (sprintf_s, itoa_s) aufschwatzen. Dadurch kann man sie wenigstens finden und ersetzen.
    In neu geschriebenem Code setzt man aber bevorzugt gleich die richtigen Versionen, die entweder mit std::string oder generischen Containern arbeiten.

    Ansonsten muss man einfach aufpassen, dass man bei std::equal und konsorten die Version mit 4 iteratoren verwendet.



  • [quote="Citizen42"]
    Gibt es eine Möglichkeit diese Kompatibilität zu C zum Teil aufzubrechen, also z.B. dass den C++-StdLibs alles erlaubt ist, nur bei selbst geschriebenen Sachen läuten dann die Alarmglocken?
    [quote].
    kannst ja die #include <c*> und #include <*.h> weglassen



  • Marthog schrieb:

    Ansonsten muss man einfach aufpassen, dass man bei std::equal und konsorten die Version mit 4 iteratoren verwendet.

    Was soll an equal unsicher sein? Eine rein lesende Operation.



  • Ethon schrieb:

    Marthog schrieb:

    Ansonsten muss man einfach aufpassen, dass man bei std::equal und konsorten die Version mit 4 iteratoren verwendet.

    Was soll an equal unsicher sein? Eine rein lesende Operation.

    int x;
    int y=*(&x+1337);
    

    ist auch eine rein lesende Operation.



  • kannst ja die #include <c*> und #include <*.h> weglassen

    So einfach ist das nicht. C++ hat glaube ich nicht alle C-Funktionen ersetzt. Z. B. gibt es die Max-Funktion in C++ erst seit C++14. Dass in Firmen schon C++14 programmiert wird, halte ich für sehr unwahrscheinlich!

    L. G.,
    IBV



  • Ethon schrieb:

    Was soll an equal unsicher sein? Eine rein lesende Operation.

    Es kann aber immernoch Abstuerze ausloesen, die z.T. schwerwiegende Folgen haben koennen. Ausserdem kann der algorithmus dadurch falsche Ergebnisse liefern, also ein Bug.



  • IBV schrieb:

    kannst ja die #include <c*> und #include <*.h> weglassen

    So einfach ist das nicht. C++ hat glaube ich nicht alle C-Funktionen ersetzt. Z. B. gibt es die Max-Funktion in C++ erst seit C++14. Dass in Firmen schon C++14 programmiert wird, halte ich für sehr unwahrscheinlich!

    Zum Glück ist programmieren nicht glauben.

    (In C gibt es keine Max-Funktion/Makro und in C++ gibt es die seit Templates, also praktisch seit immer. Argumentiere bitte mit Fakten, nicht Wahrscheinlichkeit.)



  • großbuchstaben schrieb:

    kannst ja die #include <c*> und #include <*.h> weglassen

    Was soll ich anstelle von** #include <cmath> **dann nehmen?



  • Citizen42 schrieb:

    Gibt es keine Möglichkeit sich in C++-Projekte warnen zu lassen, wenn irgendwo unsichere Funktionen der C-StdLib genutzt werden, oder wenn mit nacktem Pointer-Fu rumgespielt wird? Menschen machen garantiert Fehler, das kann man nicht wegdiskutieren.

    Doch. Profis machen solche Fehler. Aber erfahrene Profis auch?

    Lass die Wikipediaparanoia nicht an Dich ran, das wäre ein verschwendetes halbes Jahr.



  • Marthog schrieb:

    Ethon schrieb:

    Was soll an equal unsicher sein? Eine rein lesende Operation.

    Es kann aber immernoch Abstuerze ausloesen, die z.T. schwerwiegende Folgen haben koennen. Ausserdem kann der algorithmus dadurch falsche Ergebnisse liefern, also ein Bug.

    Gibt genug Dinge, die Abstürze auslösen können. equals mit 3 Parametern verwendet man halt wenn es sinnvoll ist.
    Aber für Angriffe wie vom TE genannt macht man sich damit nicht verwundbar.

    Beispiel wo ich es verwende:

    bool equal(CharT const* s) const noexcept{
    		assert(s != nullptr);
    		return std::equal(_begin, _end, s) && s[length()] == 0;
    	}
    

    equal mit 4 Parametern wäre reichlich zwecklos.



  • volkard schrieb:

    Lass die Wikipediaparanoia nicht an Dich ran, das wäre ein verschwendetes halbes Jahr.

    +1 👍



  • volkard schrieb:

    Citizen42 schrieb:

    Gibt es keine Möglichkeit sich in C++-Projekte warnen zu lassen, wenn irgendwo unsichere Funktionen der C-StdLib genutzt werden, oder wenn mit nacktem Pointer-Fu rumgespielt wird? Menschen machen garantiert Fehler, das kann man nicht wegdiskutieren.

    Doch. Profis machen solche Fehler. Aber erfahrene Profis auch?

    Lass die Wikipediaparanoia nicht an Dich ran, das wäre ein verschwendetes halbes Jahr.

    👍 😃



  • Ich zitiere mal Scott Meyers aus seinem "must read" Buch.

    Effective C++

    Mindful of the destructive power of rioting bands of incensed programmers, the standardization committee decided to create new header names for the std-wrapped components.

    The algorithm they chose for generating the new header names is as trivial as the results it produces are jarring: the .h on the existing C++ headers was
    simply dropped.

    So <iostream.h> became <iostream>, <complex.h> became <complex>, etc.

    For C headers, the same algorithm was applied, but a c was prepended to each result. Hence C's <string.h> became <cstring>, <stdio.h> became <cstdio>, etc.

    For a final twist, the old C++ headers were officially deprecated (i.e., listed as no longer supported), but the old C headers were not (to maintain C compatibility).

    In practice, compiler vendors have no incentive to disavow their customers legacy software, so you can expect the old C++ headers to be supported for many years.

    Practically speaking, then, this is the C++ header situation:

    o Old C++ header names like <iostream.h> are likely to continue to be supported, even though they aren't in the official standard. The contents of such headers are not in namespace std.

    o New C++ header names like <iostream> contain the same basic functionality as the corresponding old
    headers, but the contents of the headers are in namespace std. (During standardization, the details of some
    of the library components were modified, so there isn't necessarily an exact match between the entities in
    an old C++ header and those in a new one.)

    o Standard C headers like <stdio.h> continue to be supported. The contents of such headers are not in std.

    o New C++ headers for the functionality in the C library have names like <cstdio>. They offer the same contents as the corresponding old C headers, but the contents are in std.

    All this seems a little weird at first, but it's really not that hard to get used to. The biggest challenge is keeping all the string headers straight: <string.h> is the old C header for char*-based string manipulation functions, <string> is the std-wrapped C++ header for the new string classes (see below), and <cstring> is the std-wrapped version of the old C header. If you can master that (and I know you can), the rest of the library is
    easy.


Anmelden zum Antworten