Verwenden/Mischen von C in C++-Code?

Lesezeit: 9 Minuten

Benutzer-Avatar
Brad

Ist die Verwendung von C in C++ schlecht?

Viele Leute haben mir gesagt, dass die Verwendung von C in C++ schlecht ist, weil es nicht so sicher ist und mehr Speicherverwaltung erfordert. Ich sage ihnen immer wieder, dass C kein Problem ist, solange Sie wissen, was Sie tun, und Ihre “neuen” löschen und Ihre “malloc” freigeben.

Ich bin gerade in einem Forum wo ein Streit vorbei ist std::string gegen a char* findet statt. Einige Leute sagen, dass die Zuweisung einfach ist char* Speicherblock ist effizienter, und solange Sie ihn freigeben, ist es in Ordnung. Auf der anderen Seite haben wir Leute, die das sagen std::string ist überlegen, weil es keine Speicherverwaltung beinhaltet, aber weniger effizient ist.

Die Hauptfrage hier ist also:

  • Ist das Mischen von C/C++ schlecht? Sollten Sie NUR 100 % C++ verwenden, wenn Sie C++ programmieren?

Irgendwelche Antworten würden geschätzt!

  • C++ ist eine Obermenge von C. Daher ist jedes gültige C-Programm ein gültiges C++-Programm, und es gibt kein “Mischen” von C in C++.

    – Jonathan

    26. Oktober 2010 um 16:54 Uhr

  • @Jonathan: int main() { int class = 2; } (gültiges C, nicht gültiges C++) C++ ist keine Obermenge von C; C und C++ teilen sich eine gemeinsame Teilmenge.

    – James McNellis

    26. Oktober 2010 um 16:55 Uhr


  • @Jonathan: Oh, komm schon, du weißt genau, wovon er spricht. Niemand kann mich jemals davon überzeugen, dass printf eine C++-Funktion ist. Je

    – Armen Tsirunyan

    26. Oktober 2010 um 16:56 Uhr

  • Meinen Sie mit “Mischen”, einige Teile Ihres Projekts in C und einige Teile in C++ zu implementieren, mit einer sauberen Trennung zwischen den beiden Sprachen? Oder meinst du (wie dein dritter Absatz andeutet) das Mischen von Redewendungen aus den beiden Sprachen, um eine grässliche Hybridsprache zu erstellen?

    – Mike Seymour

    26. Oktober 2010 um 17:06 Uhr


  • @ Nick T: Wenn die FQA jemals zur Lösung einer Frage nützlich ist, muss es eine wirklich, wirklich seltsame Frage sein. Entweder das, oder Sie wollen keine Antwort, die wahr ist.

    – David Thornley

    26. Oktober 2010 um 20:56 Uhr

Benutzer-Avatar
James McNellis

Ich sage ihnen immer wieder, dass C kein Problem ist, solange Sie wissen, was Sie tun, und Ihre neuen löschen und Ihre Mallocs befreien.

Das ist wahr; Wenn Sie außerordentlich vorsichtig sind und sicherstellen, dass Sie die Dinge manuell aufräumen, ist dies kein Problem. Aber hast du wirklich die Zeit dafür? Jeder Anruf bei new werfen kann std::bad_alloc. Tust du stets Fang jeder Ausnahme, die ausgelöst werden kann und Ressourcen manuell bereinigen kann?

Ich wage zu vermuten, dass die Antwort darauf “Nein” lautet, weil es sehr mühsam ist, solchen Code zu schreiben, und es schwierig ist, absolut sicher zu sein, dass so geschriebener Code korrekt ist, selbst im Fall seltener Fehler.

Wenn die Antwort „Ja“ lautet, warum verschwenden Sie dann so viel Zeit damit, sich Gedanken über die Ressourcenverwaltung zu machen? C++-Ausdrücke wie Scope-Bounded Resource Management (SBRM; besser bekannt als Resource Acquisition is Initialization (RAII)) und Bibliotheken wie die Standard-Vorlagenbibliothek helfen Ihnen dabei, den richtigen Code einfacher zu schreiben. Warum die Dinge auf die harte Tour machen, wenn Sie nicht müssen?

Sollten Sie NUR 100 % C++ verwenden, wenn Sie C++ programmieren?

Ja, aber wenn es eine C-Bibliothek gibt, die etwas tut, was Sie brauchen, oder wenn Sie alten C-Code haben, den Sie verwenden möchten, können Sie diesen Code sicherlich verwenden. Seien Sie einfach vorsichtig. Die sauberste Art, mit C-Code zu interagieren, besteht häufig darin, einen C++-Wrapper darum zu schreiben.

  • Ich sehe nichts in Ihrer Antwort, das spezifisch für ‘C in einem C++-Projekt’ ist. Ihre Argumente scheinen im Allgemeinen nur gegen C zu sein und fallen daher in das Land der „Pick Your Poison“.

    – Javier

    26. Oktober 2010 um 17:02 Uhr

  • @Javier: Nein, meine Antwort bezieht sich speziell auf die Verwendung von C in C++-Code. Es gibt keine Ausnahmen in C, sodass Sie immer wissen, wann eine Funktion zurückkehren kann, und Sie wissen immer, wann Sie Ressourcen bereinigen müssen (abgesehen von einer verrückten Verwendung von longjmp oder sowas ähnliches). Es erfordert ein wenig Arbeit, Ressourcen in C manuell zu verwalten; es ist so gut wie unmöglich in C++.

    – James McNellis

    26. Oktober 2010 um 17:03 Uhr


  • Oh, richtig. Ausnahmen sind ein wichtiger Grund, C++ nicht von C aus aufzurufen, aber das Aufrufen von C von C++ aus ist in Ordnung (und weitaus häufiger).

    – Javier

    26. Oktober 2010 um 17:06 Uhr

  • @JamesMcNellis FFWD bis 2018 🙂 Ich möchte meinem CPP-Projekt im immer aktuellen VS2017 eine einzelne C-Datei hinzufügen … Also … Welche Version von C ist das in dieser C-Datei? Ich kann sehen, dass es nicht cpp ist, aber ich kann auch sehen, dass es nicht C99 ist. Gibt es eine Möglichkeit, das zu sagen?

    Benutzer10133158

    14. September 2018 um 10:50 Uhr

Benutzer-Avatar
Armen Tsirunjan

Ich bin fest davon überzeugt, dass Ihre Frage überhaupt nichts mit C oder C++ zu tun hat. Ihre Frage bezieht sich auf den Handel mit zweifelhafter Effizienz für Sicherheit. Ja, C kann effizienter sein. Aber wie viel effizienter? Und was zahlt man dafür? Das sind die Fragen, die Sie beantworten sollten. In den meisten Fällen ist der Overhead von string vs. const char* nicht wahrnehmbar. Wenn Sie eine effizienzkritische Anwendung entwickeln, warum codieren Sie sie dann nicht gleich in C?

  • Genau genommen bekommt man mit C++ Schnickschnack hinzugefügt (und diese reduzieren nicht unbedingt die Leistung) – aber es gibt Zeiten, in denen man Standards für rohe Leistung opfern muss (sprintf vs. iostreams, atoi (& Freunde) vs. lexical_cast etc. )

    – Nim

    26. Oktober 2010 um 17:00 Uhr

  • @Nim: Es gibt solche Zeiten, aber solche Zeiten sind extrem selten. Und machen nur einen sehr kleinen Teil unseres gesamten Codes aus. Wenn die gesamte Anwendung so zeitkritisch ist, warum nicht Assembler oder C verwenden? Das ist mein Punkt

    – Armen Tsirunyan

    26. Oktober 2010 um 17:02 Uhr

  • Es gibt viele persönliche Gründe, C gegenüber C++ zu mögen, die Leistung ist sehr gering. Wenn ich C++ mache, bevorzuge ich es, es vollständig in C++ zu machen; aber ich verstehe wirklich Abneigung gegen viele Dinge. übrigens ist std::string einer meiner unbeliebtesten, gib mir jederzeit einen char*.

    – Javier

    26. Oktober 2010 um 17:04 Uhr

  • Du denkst, du solltest eine ganze Game-Engine in Assembler schreiben, nur weil du die Leistung von Assembler für eine Handvoll mathematischer Funktionen brauchst?

    – Gerhard

    26. Oktober 2010 um 17:08 Uhr

  • @Gerald: Ich denke, dass, wenn nicht bewiesen wurde, dass Low-Level-/unsicherer/hässlicher (wohl) Code (sei es Assembly oder C) einen erheblichen Effizienzvorteil erzielen wird, der für dieses Programm benötigt wird (was es auch nicht brauchen kann). darauf sollte man nicht zurückgreifen.

    – Armen Tsirunyan

    26. Oktober 2010 um 17:11 Uhr

Benutzer-Avatar
rubenvb

Ich bin wirklich überrascht von der Polarisierung in den Antworten und Kommentaren davon.

In meinen Augen ist die Antwort ziemlich einfach:

Verwenden Sie beim Schreiben eines C++-Projekts C++, vermeiden Sie C (und Familie) und halten Sie sich an die Standardbibliothek und STL. Achten Sie auf eine homogene C++-Schnittstelle (es ist immerhin ein C++-Projekt!) Wenn Sie ein externes Projekt in C verwenden, das zufällig in C geschrieben ist, können Sie es natürlich verwenden. (siehe Beispiele unten)

Zwei Paradebeispiele:

  1. Schreiben Sie ein C++-Programm/eine C++-Bibliothek, die wissenschaftliche Berechnungen durchführt. Ich würde auf jeden Fall GSL (GNU Scientific Library) verwenden, und es ist in C geschrieben. Es gibt nur wenige Vorbehalte (wie spezialisierte Initialisierungs- und freie Funktionen für bestimmte Strukturen und Funktionen innerhalb von GSL), die in a absorbiert werden können std::unique_ptr Typdef. Es gibt auch das Problem der Fehlerbehandlung: Überprüfende Fehlercodes können bei Bedarf/Wollen in einem Ausnahmemechanismus abstrahiert werden, oder Sie können die Fehlercodes in den Berechnungsfunktionen enthalten lassen. GSL hat eine Möglichkeit, einen Fehlerbehandler einzurichten, ich kann mir vorstellen, dass einige andere C-Bibliotheken eine solche Funktionalität haben.

  2. Schreiben eines C++-Programms mit der Win32-API, die fürchterlich C-basiert ist. Ich spreche von leichter API-Nutzung, wie dem Lesen der Dateien in einem Verzeichnis, dem Prüfen, ob eine Datei existiert usw., nicht von schwerem GDI+ oder anderem Zeug. Ich verpacke gerne alle C-Funktionen, die die Win32-API bereitstellt, in nette Funktionen im C++-Stil, vielleicht mit den notwendigen Ausnahmen und der Rückgabe von a std::string statt a passieren zu müssen char* Puffer als Argument.

Ich verstehe, dass beide Beispiele ziemlich … oberflächlich sind … aber ich denke, sie drücken eine allgemeine Idee aus.

Benutzer-Avatar
UnixShadow

Ja, es ist schlecht, C und C++ zu mischen, und der Grund hat nichts mit Leistung oder Sicherheit zu tun:

Es ist eine schlechte Ursache für eine Wartbarkeit:

  • Ein C++-Programmierer erwartet, dass sich der gesamte Code wie C++ verhält.
  • Ein C-Programmierer erwartet, dass sich der gesamte Code wie C verhält.

Wenn Sie also C++ und C mischen, brechen Sie die Erwartungen beider Programmierer, wie die Dinge funktionieren sollten.

Die Antwort ist natürlich: Es kommt darauf an.

Im Allgemeinen möchten Sie vermeiden, Dinge zu mischen, die Verwirrung stiften können, was weiter zu schwer zu findenden Fehlern führen kann. Nur weil “Sie wissen, was Sie tun”, bedeutet das nicht, dass die nächste Person, die Ihren Code berührt, weiß, was Sie getan haben. Wenn Sie Code entwickeln, den nur Sie jemals verwenden werden, dann ist es das wahrscheinlich okay, aber das ist selten der Fall.

Die Verwendung von C für die Leistung ist in Ordnung, wenn Sie vorsichtig sind. Aber man sollte es nur tun, wenn man WISST, dass man die Leistung braucht. Vorzeitige Low-Level-Optimierung ist das Werk des Teufels.

Es ist ein sehr seltener Fall, in dem die Verwendung von char* über std::string Ihnen spürbare Leistungsvorteile bringt, und es lohnt sich nur in den Fällen, in denen dies mit Sicherheit der Fall ist, den Aufwand für die Speicherverwaltung.

Benutzer-Avatar
Welpe

Die bessere Frage hier ist, warum C verwenden? Die Performance? Erstens glaube ich, dass es keinen messbaren Leistungsunterschied für ein Programm mit der gleichen Funktion gibt. Zweitens müssten Sie profilieren und beweisen, dass C++ für Ihren speziellen Fall langsamer ist. Drittens geben Sie eine große Menge an Anwendungssicherheit auf, indem Sie C anstelle von C++ verwenden.

Benutzer-Avatar
6bf6411707

In Bezug auf den Streit vorbei std::string vs char*:

std::string wird nicht langsamer sein als char* (für Haufen char*); Viele Implementierungen sind viel schneller, weil sie einen privaten Speicherpool verwenden. Und überhaupt die Robustheit von std::string überwiegt bei weitem jeden (unwahrscheinlichen) Performance-Hit.

  • Und selbst wenn die Umsetzung ist nicht schneller als die Verwendung von Zeichenfolgen im C-Stil, die Nützlichkeit der string Klasse gleicht Leistungsverluste meiner Meinung nach aus. Tauschen Sie Wartbarkeit und Lesbarkeit nicht gegen Leistung ein wenn nicht Sie erfüllen eine harte Leistungsanforderung nicht und Sie haben bereits alle möglichen High-Level-Optimierungen durchgeführt.

    – Johannes Bode

    26. Oktober 2010 um 18:10 Uhr

1365520cookie-checkVerwenden/Mischen von C in C++-Code?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy