Wann sollte C über C ++ und C ++ über C verwendet werden?


164

Ich bin jetzt seit etwas mehr als einem Jahr mit der Informatik vertraut, und meiner Erfahrung nach scheinen C und C ++ beide als "ultraschnelle" Sprachen zu gelten, während andere wie Python und solche Skriptsprachen normalerweise als etwas langsamer gelten .

Aber ich habe auch viele Fälle gesehen, in denen ein Softwareprojekt oder sogar ein kleines Projekt Dateien verschachtelte, in denen eine bestimmte Anzahl n dieser Dateien in C und eine bestimmte Anzahl m dieser Dateien in C ++ geschrieben wurden.

(Mir ist auch aufgefallen, dass C ++ - Dateien fast immer entsprechende Header haben, während C-Dateien nicht so sehr). Mein Hauptanliegen ist es jedoch, ein allgemeines Gespür dafür zu entwickeln, wann es angebracht ist, C über C ++ zu verwenden, und wann es besser ist, C ++ über C zu verwenden C ist nicht, und (2) die Syntax ist sehr ähnlich, und C ++ wurde absichtlich erstellt, um C in vielerlei Hinsicht zu ähneln. Ich bin nicht sicher, was ihre Unterschiede sind. Es scheint mir, dass sie in vielen Bereichen (fast) perfekt austauschbar sind.

Es wäre also sehr dankbar, wenn jemand die Situation klären könnte! Vielen Dank


4
Die Verwendung von C-Inline in C ++ - Code gilt normalerweise für bestimmte Module, die in hohem Maße optimiert werden müssen, auf sehr niedriger Ebene näher an der Hardware arbeiten oder für die Integrität der Daten oder sogar für die Sicherheit des Menschen von entscheidender Bedeutung sind und nachweislich überprüft werden müssen. Anstatt alles in C zu erledigen, kann der Großteil des Projekts die C ++ - Funktionen für flexible Entwürfe nutzen und gleichzeitig die Vorteile der Dichtheit von C an den Stellen nutzen, an denen dies erforderlich ist.
Kylben

30
@kylben: Viele C ++ - Leute werden Ihnen sagen: (1) Leistung ist kein Grund, auf C zu verzichten (vielleicht, um virtualeinige andere Funktionen zu vermeiden, die Optimierungen verhindern, aber z. B. sind Nicht- virtualKlassen nicht von Natur aus ineffizient, und Vorlagen sind a leistungsfähiges Abstraktionswerkzeug, das tatsächlich zu mehr Effizienz führen kann - zB qsortvs std::sort). (2) Hohe Wichtigkeit der Korrektheit ist ein Grund, C ++ (Typensicherheit, constNess, privateRAII, um das Ressourcenmanagement überschaubar zu machen, etc.) über C zu verwenden. Oder verwenden Sie Ada oder etwas anderes .

11
@ Pubby8 Ich bin damit nicht einverstanden. Wenn ich an einer .c-Datei arbeite und ich sehe, dass Leute dies tun, neige ich dazu, sie mental als nicht wissend zu markieren, was sie tun. Zum Beispiel gibt es keine Notwendigkeit von werfen void*in einen anderen Zeigertyp in C - Code, es ist sehr störend und typisch für Menschen , die C nicht wissen
asveikau

4
@kylben: (Vielleicht möchten Sie lernen, andere in Ihren Kommentarantworten richtig anzusprechen, damit sie sie tatsächlich sehen können.) Dass "ein Programmierer, der sehr gut mit der Umwandlung von C in asm durch den Compiler vertraut ist" für C ++ genauso funktionieren würde Gut. Aber das ist einfach irrelevant: Wenn Sie sich in asm versuchen möchten, schreiben Sie asm, anstatt es von einem Compiler aus einer anderen Sprache erstellen zu lassen. Die Art und Weise kann sich schließlich mit jedem Compiler-Update ändern.
sbi

9
Meiner bescheidenen Meinung nach ... verwenden Sie C, wenn Sie wollen, für mich: C ist viel einfacher und benutzerfreundlicher als C ++ ... C ++ könnte wie ein "C mit Klassen" aussehen, ist es aber nicht mehr, jetzt ist es eine sehr komplexe Sprache mit Dingen wie virtuellen Konstruktoren und Vorlagen.
Dysoko

Antworten:


184

Sie wählen C wann

  • Sie brauchen einen portablen Assembler (was eigentlich C ist), aus welchem ​​Grund auch immer,
  • Ihre Plattform bietet kein C ++ (ein C-Compiler ist viel einfacher zu implementieren),
  • Sie müssen mit anderen Sprachen interagieren, die nur mit C interagieren können (normalerweise der kleinste gemeinsame Nenner auf einer Plattform), und Ihr Code besteht nur aus der Schnittstelle, sodass es sich nicht lohnt, eine C-Schnittstelle über C ++ - Code zu legen.
  • Sie hacken in ein Open Source-Projekt (viele davon halten sich aus verschiedenen Gründen an C),
  • Sie kennen C ++ nicht.

In allen anderen Fällen sollten Sie C ++ auswählen.


15
Ich würde auch hinzufügen, dass C ++ mit Ausnahmemodellen manchmal mehr Probleme mit sich bringt, als es zum Beispiel für Betriebssystem-Kernel wert ist. Zumindest ist das das allgemeine Gefühl, das ich beim Lesen über Sachen bekommen habe.
Coder

12
@SF: C ist die Verkehrssprache? Das ist neu. Oder vielmehr sehr alt. Vielleicht, wenn Sie sich nur mit Leuten unterhalten, die in den letzten 20 Jahren keine neuen Sprachen gelernt haben, aber ich würde sagen, dass C-Kenntnisse nicht mehr sehr verbreitet sind.
DeadMG

13
@SF .: Wie ich bereits an anderer Stelle geschrieben habe, habe ich an Projekten mit einem Umfang von Millionen von LoC mitgewirkt und im Vergleich zu C-Projekten mit ihrer unvermeidlichen und allgegenwärtigen Makrohackerei nur sehr wenige Meta-Inhalte gesehen. (OTOH, die Fähigkeit, EDSLs bei Bedarf zu erstellen, kann ein unglaublich leistungsfähiges Werkzeug in Ihrer Box sein.) Was C als Verkehrssprache anbelangt: Ich halte lieber an meinem Begriff fest, dass es der kleinste gemeinsame Nenner ist. Und ich würde nicht wollen, dass Leute mit moderaten Programmierkenntnissen einen Betriebssystemkern hacken.
sbi

18
@Max: Da stimme ich überhaupt nicht zu. C ist eine nutzlose Sprache, es sei denn, eine unüberwindbare praktische Barriere verhindert die Verwendung von C ++.
DeadMG

17
@Buttons: Sie haben eine Behauptung aufgestellt ("C ++ benötigt mehr Speicher"), also sollten Sie es sein, der diese Behauptung sichert. Und nein, ich behaupte nicht, dass C ++ weniger Speicher benötigt. Was ich sage ist, dass Features kosten, egal ob der Compiler sie für Sie implementiert (virtuelle Funktionen) oder Sie sie selbst machen (Array von Funktionszeigern).
sbi

88

Es gibt einige Gründe, C zu bevorzugen. Der Hauptgrund ist, dass es schwieriger ist, wirklich winzige ausführbare Dateien mit C ++ zu erstellen. Bei wirklich kleinen Systemen schreiben Sie sowieso selten viel Code, und der zusätzliche ROM-Speicherplatz, der für C ++ und nicht für C benötigt wird, kann erheblich sein.

Ich sollte jedoch auch hinzufügen, dass C bei wirklich kleinen Systemen aus genau demselben Grund Probleme hat und die Assemblersprache fast die einzige vernünftige Wahl ist. Der Bereich der Systemgrößen, innerhalb dessen C wirklich Sinn macht, ist recht klein und schrumpft ständig (obwohl ich zugeben werde, ziemlich langsam).

Ein weiterer Grund für die Verwendung von C besteht darin, eine Reihe von Funktionen bereitzustellen, an die Sie sich aus praktisch jeder anderen Sprache binden können. Sie können diese Funktionen in C ++ schreiben, indem Sie sie als extern "C"Funktionen definieren. Dadurch werden diese Funktionen jedoch darauf beschränkt, den Weltklassen ein im Wesentlichen C-life-Gesicht zu präsentieren - Klassen, überladene Funktionen, Vorlagen und Memberfunktionen usw. müssen dies nicht tun anwenden. Dies beschränkt die Entwicklung jedoch nicht unbedingt auf C - es ist durchaus sinnvoll, alle C ++ - Funktionen intern zu verwenden , solange die externe Schnittstelle wie C aussieht.

Gleichzeitig muss ich sagen, dass die Antworten von @ Toll (für ein offensichtliches Beispiel) in den meisten Hinsichten fast rückwärts sind. Vernünftigerweise geschriebenes C ++ ist in der Regel mindestens so schnell wie C und häufig mindestens etwas schneller. Die Lesbarkeit ist in der Regel viel besser, schon allein deshalb, weil Sie nicht in eine Lawine des gesamten Codes für die einfachsten Algorithmen und Datenstrukturen, die gesamte Fehlerbehandlung usw. vergraben werden.

Templates "beheben kein Problem mit dem Typensystem der Sprache", sondern fügen einfach eine Reihe grundlegender Funktionen hinzu, die in C und / oder C ++ ohne Templates fast nicht vorhanden sind. Eine der ursprünglichen Absichten war es, typsichere Container bereitzustellen, aber in Wirklichkeit gehen sie weit darüber hinaus - im Wesentlichen keine, die C überhaupt bereitstellt.

Automatisierte Tools sind meistens auch ein roter Faden - während das Schreiben eines C-Parsers weniger Arbeit kostet als das Schreiben eines C ++ - Parsers, macht es letztendlich praktisch keinen Unterschied. Nur sehr wenige Leute sind bereit oder in der Lage, einen verwendbaren Parser für einen der beiden zu schreiben. Angemessener Ausgangspunkt ist also Clang.

Zufällig werden C und C ++ ziemlich häufig zusammen in denselben Projekten verwendet, die von denselben Personen verwaltet werden. Dies ermöglicht etwas, was ansonsten ziemlich selten ist: eine Studie , die die Wartbarkeit von Code, der in zwei Sprachen von Personen geschrieben wurde, die insgesamt gleich kompetent sind (dh genau dieselben Personen), direkt und objektiv vergleicht. Zumindest in der verknüpften Studie war eine Schlussfolgerung klar und eindeutig: "Wir haben festgestellt, dass die Verwendung von C ++ anstelle von C zu einer Verbesserung der Softwarequalität und einem geringeren Wartungsaufwand führt ..."


12
Werkzeugträger ist kein roter Hering. Zugegeben, heutzutage haben wir geklungen. Die Tool-Unterstützung für C ++ bleibt jedoch auch in den Big Shot-IDEs erheblich zurück. Warum ist das so? Einfach, denn bis vor kurzem gab es keine Klänge (und GCC war nie eine Alternative). Bis vor einem halben Jahr, als Sie einen AST mit C ++ - Code brauchten, hatten Sie im Grunde Pech oder hatten nicht genug Geld (wenn Sie das EDG-Frontend gekauft haben).
Konrad Rudolph

5
+1, und für den Datensatz schreibe ich regelmäßig C ++ - Code für 8-Bit-Prozessoren mit 4 KB ROMs.
Avakar

2
+1 für eine insgesamt gute Antwort. Was ich nicht verstehe (ich habe keine Erfahrung damit) ist, warum (ich denke, wir reden eingebettet?) Ein C-Compiler einen kleineren ausführbaren Code erzeugen sollte als ein C ++ - Compiler, wenn derselbe Funktionsumfang verwendet wird ? Vielleicht könnten Sie einige Referenzen angeben?
Martin Ba

2
@Martin: Die Hauptsache ist, dass C ++ eine Ausnahmebehandlung beinhaltet, die (zumindest normalerweise) ein Minimum zur ausführbaren Größe hinzufügt. Bei den meisten Compilern können Sie die Ausnahmebehandlung deaktivieren, aber wenn Sie dies tun, ist das Ergebnis nicht mehr ganz C ++. Ich vermute, es liegt auch etwas an der einfachen Tatsache, dass viele C ++ - Compiler-Anbieter nicht so hart daran arbeiten, den kleinstmöglichen Ausgabe-Code zu produzieren.
Jerry Coffin

3
"Wir haben festgestellt, dass die Verwendung von C ++ anstelle von C zu einer Verbesserung der Softwarequalität und zu einem geringeren Wartungsaufwand führt ..." Dies ist eine unvergessliche Schlussfolgerung.
Stephane Rolland

24

Die Unterschiede zwischen C und C ++ wurden bereits ausführlich aufgezählt wurden hier . Während Menschen manchmal legitime Gründe haben, sich für das eine oder andere zu entscheiden (C ++ für OOP oder C, wenn sie der Meinung sind, dass die zusätzlichen Funktionen von C ++ beispielsweise unerwünschten Overhead verursachen), kommt es meiner Erfahrung nach in der Regel nur auf die Präferenz an. Was wissen die Leute, die an dieser Datei arbeiten, besser und mögen es besser? Ich glaube, dies ist der Grund für die meiste Zeit, da beide Sprachen leistungskritische Anwendungen angehen.

( Randbemerkung : Sehen Sie sich an, warum Linus Torvads C gegenüber C ++ bevorzugt. Ich bin nicht unbedingt mit seinen Argumenten einverstanden, aber es gibt Ihnen einen Einblick, warum Menschen C gegenüber C ++ wählen. Vielmehr Menschen, die ihm zustimmen könnte aus diesen Gründen C wählen.)


51
-1für Linus 'Schimpfen. : - {
sbi

12
Nicht abzüglich eins mich dafür! Haha. Ich bin nicht mit Linus einverstanden, aber es ist ein ziemlich gutes Beispiel dafür, warum Leute C gegenüber C ++ wählen (wenn sie glauben, was Linus glaubt). Ich kommentiere die Rechtmäßigkeit dieser Gründe nicht.
Casey Patton

10
@CaseyPatton: Grundsätzlich habe ich jede Antwort abgelehnt, die diese rhetorische Parole kommentarlos darstellt, als wäre sie ein echtes Argument.
sbi

11
@Coder: Sie müssen die STL-Implementierung überhaupt nicht kennen. Der eigentliche Punkt der STL ist, dass Sie die Implementierung nicht kennen müssen, es sei denn, Sie verlassen sich auf ein Verhalten, das nicht durch den Standard definiert ist. In welchem ​​Fall sollten Sie die Standardbibliothek verwenden? Darüber hinaus ist es mehr als verrückt, eine Sprache nicht zu mögen, weil sich die Entwickler so verhalten. C-Programmierer verhalten sich wie C, das Geschenk Gottes an den Menschen, und sind zu blind, um die offensichtliche Wahrheit zu erkennen, dass C ++ Funktionen bietet, die C grundsätzlich und direkt überlegen sind, wie RAII.
DeadMG

8
@Coder: Wenn Sie am Ende so viele shared_ptrs für ein einzelnes Objekt haben, dass Sie den internen Zähler überlaufen, machen Sie es falsch. Der Standard legt eine Mindestgröße für den Zähler fest - wahrscheinlich 32 Bit - und es ist ziemlich unrealistisch, mehr als 2 Milliarden shared_ptrs für ein einzelnes Objekt zu haben. Selbst wenn das Objekt selbst eine Größe von 0 hatte und Sie über einen Speicherzuweiser ohne Overhead verfügten, verbrauchen Sie immer noch 16 GB Speicher, nur auf shared_ptrs.
DeadMG

13

Das Hauptproblem, das in den vorhandenen Antworten (zum Zeitpunkt der Veröffentlichung) fehlt, ist die Wahl.

Es ist einfach. Wenn Sie aus einem völlig irrationalen Grund der Meinung sind, dass Ausnahmen den Aufwand nicht wert sind, müssen Sie sie nicht verwenden . Sie können weiterhin Vorlagen, RAII und die Standardbibliothek haben und niemals einen einzigen "Wurf" schreiben. Gleiches gilt für Vorlagen. Wenn Sie aus irgendeinem Grund das Gefühl haben, dass sie unwiderrufliches (und eigentlich wichtiges, nur eingebettetes) Aufblähen verursachen, können Sie überraschenderweise auch void * und sizeof (T) den ganzen Tag verwenden. Nichts zwingt Sie, eine der C ++ - Funktionen über C zu verwenden.

Aus diesem Grund ist C ++ eine von Natur aus überlegene Sprache. Sie können die gewünschten Funktionen auswählen und auf die Programmierung im C-Stil zurückgreifen, wenn Sie eine bestimmte Funktion nicht mögen. Angesichts der Tatsache, dass C ++ alles ist, was C ist, und darüber hinaus, ist es eine offensichtliche Tatsache, dass C ++ eine überlegene Sprache ist. Andernfalls vorzuschlagen ist wie der Versuch, vorzuschlagen, dass 4 größer als 5 ist.


1
Nach Ihrer Überlegung hat die ursprüngliche Frage überhaupt keinen Sinn und sollte daher geschlossen werden. Ich denke, die Frage sollte in etwa so lauten: Wann sollten wir uns auf die C-Teilmenge von C ++ beschränken (verwenden Sie einfaches C) und wann ist es sinnvoll, volles C ++ zu verwenden.
Giorgio

Dies gilt jedoch nur für den Fall, dass eine Person an ihrem eigenen kleinen Projekt arbeitet. Im wirklichen Leben verbringt fast jeder die Hälfte seiner Zeit damit, an dem Code anderer Leute zu arbeiten. Leider "denken" die meisten anderen Menschen aus diesen völlig irrationalen Gründen falsch.
DarenW

1
@DeadMG: Wie sollen Allokatoren Fehler melden, ohne Ausnahmen auszulösen? Außerdem ist das Hinzufügen weiterer Funktionen nicht unbedingt besser, wenn nur Komplexität oder Redundanz hinzugefügt werden.
Mankarse

@Mankarse: Wenn Sie mit den Optionen zum Deaktivieren von Ausnahmen kompilieren, brechen Zuweiser das Programm ab oder verwenden fröhlich einen Nullzeiger, abhängig von der Bibliotheksimplementierung.
Zan Lynx

4
@Mankarse: Seit meiner Erfahrung im Jahr 2007, als ich versuchte, ein Linux-System mit 1 GB RAM und ohne Swap auszuführen, versagt fast jede Desktop-Software auf schreckliche Weise, wenn die Speicherzuweisung trotzdem fehlschlägt.
Zan Lynx

9

Dinge über C ++, die C-Programmierer nervös machen

Unter der Motorhaube geschieht viel Magie. Konstruktoren, Destruktoren, virtuelle Methoden, Vorlagen usw. können dazu führen, dass C ++ - Code viel einfacher und schneller zu schreiben ist als der entsprechende C - Code, jedoch schwieriger zu verstehen und zu durchdenken (je nachdem, wie gut Sie C ++ und die damit verbundenen Konventionen kennen). Etwas so Einfaches wie Foo newFoo;kann eine Menge Code aufrufen , abhängig davon, wie der Konstruktor für die Klasse Foo(und alle Klassen, von denen er abhängt) definiert wurde. Dies ist auch der Grund, warum die Konvention lautet, ++itstatt it++durch einen Container zu iterieren, da Postfix ++oft einen teuren Kopiervorgang beinhaltet.

Je nachdem, was Sie gerade tun, kann es zu nicht trivialem Overhead kommen, insbesondere bei einfachen Aufgaben. Nehmen Sie die folgenden zwei Programme, das erste in C, das zweite in C ++:

/* C version */
#include <stdio.h>
int main(void)
{
  char greeting[] = "Hello, world";
  printf("%s\n", greeting);
  return 0;
}
/* end C version */

/* C++ version */
#include <iostream>
#include <string>
int main(void)
{
  std::string greeting("Hello, world");
  std::cout << greeting << std::endl;
  return 0;
}
/* end C++ version */

Identisches Verhalten, kein großer Unterschied in Bezug auf die Quelle, aber auf der SLES 10-Box, an der ich mit gcc 4.1.2 arbeite, generiert die erste eine ausführbare Datei mit einer Größe von ~ 9 KB, während die zweite 12,5 KB überschreitet (keine Optimierung) ), fast 28% größer. Der C ++ - stringTyp ist viel einfacher mit IMO zu arbeiten als die C-Zeichenfolgenbibliothek, und C ++ - Streams sind viel flexibler und anpassbarer als C-Streams, aber für wirklich hirntoten Code wie diesen lohnt sich der Aufwand möglicherweise nicht.

C ++ ist im Vergleich zu C eine riesige Sprache mit extrem komplexer Semantik. Das Erlernen von C ++ dauert viel länger als das von C, was bedeutet, dass viele Leute, die behaupten, C ++ zu kennen, es nicht so gut kennen, wie sie denken.

Dinge über C, die C ++ - Programmierer nervös machen

C ist keine sichere Programmiersprache. Die Überprüfung von Arrays ohne Einschränkungen führt zu einer Vielzahl von ausnutzbaren Verhaltensweisen (sei es durch die getsFunktion now-dead oder durch scanfdie Spezifizierer %sand und %[conversion). Zumindest in C ++ gibt es Container, die Ausnahmen auslösen, wenn Sie versuchen, außerhalb des aktuell definierten Bereichs zuzugreifen. Alles, was C gibt, ist (wenn Sie Glück haben) eine Verletzung der Segmentierung.

Die Speicherverwaltung in C ist sehr arbeitsintensiv und fehleranfällig im Vergleich zu den von C ++ bereitgestellten Tools. Wenn Sie einen eigenen Container erstellen, müssen Sie alle Aufrufe mallocund abgleichen free, sicherstellen, dass die Zuweisungen erfolgreich sind, und alle Teilzuweisungen im Fehlerfall zurücksetzen. In C ++ fügen Sie einfach Elemente zu oder hinzu Gegenstände aus dem Behälter entfernen. Wenn es ein Problem gibt, wird eine Ausnahme ausgelöst.

In ähnlicher Weise ist die Fehlerbehandlung in C im Vergleich zu den Tools, die C ++ bereitstellt, ein Nervenkitzel (nämlich Ausnahmen). Was wirklich Spaß macht, ist, wenn Sie eine Menge Speicher zugewiesen haben und dann in Ihrer Verarbeitung an eine Wand stoßen. Wenn Sie zurücktreten müssen, müssen Sie diesen Speicher in der richtigen Reihenfolge freigeben. Mit C ++ und RAII ist dies (relativ) einfach zu bewerkstelligen.

Also, wann verwende ich eins übereinander?

Wenn das, was Sie schreiben, nicht einfach ist, lesen Sie es, spielen Sie damit herum, und entfernen Sie die Anwendung, deren Verhalten in Bezug auf Ein- und Ausgaben und Leistungsaspekte klar beschrieben werden kann. Dann ziehen Sie C C ++ vor. Ansonsten lieber C ++


2
Die Speicherverwaltung ist in einigen Fällen komplex und fehleranfällig, aber insbesondere in der Embedded-Welt ist es häufig praktisch, C-Programme mit vollständig statischer Speicherzuordnung zu schreiben. Wenn das Programm eine Verbindung herstellt, kann zur Laufzeit nicht genügend Speicher verfügbar sein. Können solche Garantien in C ++ leicht erreicht werden?
Supercat

9

Bjarne Stroustrup führt eine Liste der Anwendungen und Unternehmen , die C ++ verwenden. Sie können sich über verfahrenstechnische vs. OOP-Programmierung streiten, was Sie wollen, aber Sie können sich nicht mit den Branchenergebnissen der letzten 20 Jahre streiten.

C ++ wird häufig für komplexe Großprojekte mit mehreren Mitarbeitern verwendet , bei denen separate Personen an modularisierten Komponenten arbeiten müssen. Sie können modularisierten Code natürlich in C erstellen und verwalten, aber die inhärente OOP-Eigenschaft von C ++ führt zu überlegener Modularisierung, Testbarkeit und Wiederverwendung von Code.

Die C ++ - Standardbibliothek (STL) allein mit Vektoren und Karten ist Grund genug, C ++ zu verwenden.

C wird üblicherweise für eingebettete Systeme verwendet.

Ich persönlich würde C nur verwenden, wenn es eine Bibliothek gibt, die nur eine C-API hat.


19
Ihr letzter Satz ist kein Grund, C zu verwenden. Sie können C-Bibliotheken von C ++ aus aufrufen.
user207421

2
Ich habe c ++ für ein DSP-Projekt verwendet - nicht c
BЈовић

9

Ich würde sagen, dass der Hauptgrund, warum ich C gegenüber C ++ wählen würde, nur dann ist, wenn ich auf NASA-Sachen wie "It this HAS TO BE 1000% stable" zurückgreifen müsste.

C ++ ist ~ 99% C, wenn wir die Leistung betrachten, und es ist viel produktiver. Selbst in C können Sie Code schreiben, der schneller ist als C ++ (Sie können auch eine Teilmenge von C ++ ohne Ausnahmen, virtuell, Streaming, Abstraktionen usw. verwenden, aber das ist im Grunde genommen C), die Zeit, um jedes verdammte Ding zu optimieren Während STL getestet wird und dies bereits tut, würde es Sie mehr kosten als den winzigen Leistungsgewinn, den Sie erzielen könnten, oder Sie würden Opfer bringen, da STL-Algorithmen von Expertengruppen geschrieben wurden und Sie wahrscheinlich nicht in allen Dingen ein Experte sind.

Andererseits hat C ++ eine Menge Abstraktionen. Wenn sie unter Umständen auslaufen, geraten Sie in Schwierigkeiten. Und es gibt nur wenige Leute, die 100% der C ++ - Fallstricke kennen, während es vermutlich mehr gibt, die alle C-Fallstricke kennen. Daher ist es in C viel einfacher, eine Lösung zu schreiben, bei der jeder Schritt von allen Mitgliedern eines Teams vollständig verstanden wird.

Beispiel: Wissen Sie, wann shared_ptr<smthn>der Referenzzähler überläuft, wird eine Ausnahme ausgelöst? Solche Dinge sind nicht cool, wenn Shuttle die Atmosphäre wieder betreten muss, denke ich zumindest.

Außerdem ist die Ausnahmebehandlung im Vergleich zu Fehlercodes sehr, sehr schwierig. Es ist schwer zu erkennen, ob die Klasse zu 100% ausnahmesicher ist und es leicht ist, auf Lecks zu stoßen. Viele hochrangige Vertreter haben diese Meinung geäußert.


12
Und auf welche Weise ist die manuelle Speicherverwaltung "stabiler" als die von C ++ - std::stringund ähnlichen Abstraktionen ? Haben Sie jemals versucht, eine Plattform anzugeben, auf shared_ptrder der Zähler überlaufen würde? Das wäre eine verdammt lustige Plattform. Und wenn Sie der Meinung sind, dass die Behandlung von Ausnahmen schwierig ist, sollten Sie sich einen Teil des C-Codes ansehen, der bei jedem Funktionsaufruf nach möglichen Fehlern sucht. (Ein solcher Code ist schwer zu bekommen, ich gebe zu, aber dies ist nur ein noch stärkeres Argument gegen Ihre Aussage.) Entschuldigung, aber das sind wirklich Rinder-Exkremente.
sbi

12
@Lundin: "Es muss zu 1000% stabil sein" Implementierungen erlauben überhaupt keine dynamische Speicherzuweisung. Und was hält Sie davon ab, genau das in C ++ zu tun? (Und pauschale Aussagen über mein Wissen und meine Erfahrung zu machen, anstatt irgendwelche Argumente zu liefern, ist ein ziemlich billiger Rhetoriktick.)
sbi

10
@Lundin: Gut, dass Sie angefangen haben, Argumente und keine Rhetorik zu liefern. Aber sie sind schwach. Dass Sie eines der Hauptmerkmale von C ++ (Templates) "vergessen" haben, das den Code sicherer macht (weil damit Algorithmen zur Kompilierungszeit ausgeführt werden können - und somit fehlschlagen - , wodurch Laufzeitfehler vermieden werden), ist nicht der Fall sprechen Sie für Ihre Kenntnisse der Sprache, die Sie beurteilen. Die Reduktion von C ++ auf eine OO-Sprache wurde bereits aus guten Gründen kritisiert. (Außerdem sind Klassen mit deterministischer Zerstörung ein großartiges Werkzeug und hilfreich für die Verwaltung anderer Ressourcen als nur des Gedächtnisses.)
sbi

9
@Lundin Natürlich möchten Sie nicht verwenden, std::stringwenn Sie keine dynamische Zuordnung möchten. Du würdest benutzen std::basic_string<char, std::char_traits<char>, some_allocator_here>.
Luc Danton

10
@Coder: Was glaubst du, beweist du damit? Der erste ist einfach schlechter Code (und würde genauso schlechte Fehler melden wie Rückgabewerte), der zweite ist ein Argument für RAII über die manuelle Bereinigung, zu der jeder halbwegs anständige C ++ - Entwickler und Joel ebenso jubeln würden wie ich respektiere ihn, habe ein paar Dinge gesagt, mit denen ich überhaupt nicht einverstanden bin. Sein Plug für Single-Entry-Single-Exit stinkt schlecht nach einem uninformierten alten Furz, der niemals zustimmen wird, dass das, was er vor 25 Jahren gelernt hat, übertroffen wird. ( Wohlgemerkt , ich habe vor 25 Jahren programmiert, als SESE auf dem neuesten Stand war.)
sbi

6

C ist eine portable Assembly mit besserer Syntax, die dem Programmierer die volle Kontrolle über alles gibt .

C ++ hingegen macht eine Menge Funky Magic (virtuelle Funktionen, Überladung, automatische Konvertierung usw. usw.), was möglicherweise nicht wünschenswert ist, wenn Sie sicherstellen möchten, dass Sie:

  • Verwenden Sie nicht mehr Speicher, als Sie möchten
  • greife nicht umsonst auf Speicherseiten zu (die vtable kann überall sein)
  • Rufen Sie nicht versehentlich zu viel Code auf

Und möchten Sie etwas wirklich Einfaches, da Sie sich auf Leistung konzentrieren.

Es hat einfach keine Überraschungen und das ist sehr wertvoll.

Wenn Sie möchten (und ich empfehle es), lesen Sie in den JSF-Codierungsrichtlinien nach, worauf Sie beim Schreiben von C ++ für die militärische Avioniksteuerung achten müssen. Es gibt dort eine Menge Fallen, auf die Sie achten müssen, und es kann Sie auffangen. Bjarne war Teil dieses Dokuments, also weiß er, worum es geht.

Außerdem kompiliert C wie ein verbrühter Troll, der vom Blitz getroffen wird. C ++, OTOH, wurde wahrscheinlich von denselben Personen gesponsert, die in SSD-Unternehmen investiert haben. :)

(Ich persönlich bevorzuge C ++, aber ich mag es auch nicht ...... ;-P)


1
Es gibt eine Menge Dinge, über die C keine Kontrolle bietet. Versuchen Sie, effizienten portablen Code zu schreiben, um ein uint32_t mit einem uint32_t zu multiplizieren und ein uint32_t-Ergebnis zu erhalten (unterste 32 Bit des Produkts). Wenn an int64 Bit ist, muss man mindestens einen Operanden umwandeln, uint64_tum Undefiniertes Verhalten zu verhindern, aber auf 64 Bit umwandeln zu müssen , um ein 32-Bit-Ergebnis zu berechnen, ist - gelinde gesagt - "überraschend".
Supercat

Es ist nicht. Der Compiler erledigt Dinge wie die Zuweisung von Registern für Sie. Ich kann keinen wartbaren Code in Assembly schreiben, in CI kann.
Nils

2

(vorausgesetzt du kennst beide Sprachen gleich gut)

Fahren Sie mit C ++ fort, es sei denn, es gibt keinen C ++ - Compiler für Ihre Plattform. Sie können C ++ - Code ohne einen Teil der Sprache schreiben, die Sie nicht mögen (keine Klassen, Ausnahmen, virtuelle Vererbung, beliebige persönliche Einschränkungen, die Sie anwenden möchten), und dann irgendwann in der Zukunft, wenn Sie dies wünschen Diese Funktionen können Sie dann ganz einfach nutzen. Nichts in C ++ hindert Sie daran, Code im C-Stil zu schreiben.

Es gibt keinen Grund, C anstelle von C ++ zu wählen, vorausgesetzt, Ihre Plattform verfügt über einen C ++ - Compiler. Sie können sich einfach auf die Teilmenge der Sprache beschränken, die Sie heute möchten, und die Tür für eine spätere Erweiterung offen lassen.


1

Beide Sprachen sind ausgezeichnet. Ich denke, eine Reihe von Postern hat die Stärken und die verschiedenen Verwendungszwecke für jeden genau beschrieben. Ich füge einfach Folgendes hinzu:

Ich sehe die C-Sprache in 4 Bereichen als perfekt an: 1) Ich denke, dass es die beste Sprache ist, wenn man zum ersten Mal irgendeine Art von Programmierung lernt [kombiniert mit etwas Assembler- und Maschinencode-Kenntnissen], 2) es ist großartig, Treiber zu schreiben, 3) eingebettet Software und 4) Systemsoftware auf der untersten Ebene.

C ++ ist eine objektorientierte Sprache, kann aber auch prozedural sein (sehr ähnlich wie C). Wenn Sie an großen Projekten, GUI-basierter Software, Spielesoftware und anderen Arten von grafisch intensiver Software arbeiten, dann ist C ++, Java oder sogar Objective-C für mich die beste Wahl. Es gibt jedoch viele Befehlszeilenprogramme oder Systemsoftware, in denen C ++ möglicherweise genauso gut oder besser als C ist.


0

Meiner Meinung nach fehlt in dieser Diskussion ein Punkt: In C ist es einfacher, eine stabile binäre Schnittstelle aus einer Bibliothek bereitzustellen. Sowohl für die Verwendung mit anderen Sprachen als auch mit C ++.

In C ++ verwenden verschiedene Compiler unterschiedliche Namensverwaltungen, sodass es bei Verbrauchern einer Bibliothek, die mit einem anderen Compiler als der Bibliothek kompiliert wurde, zu Problemen bei der Verwendung kommen kann. Mit C ist die Binärschnittstelle in der Regel für die Plattform standardisiert.

Ich weiß, dass Compiler heutzutage oft Schalter haben, um gcc-kompatible Dinge zu produzieren, aber das hilft nicht immer.

Ich beobachte dies relativ oft unter Solaris. Die Distribution und verschiedene Softwareanbieter verwenden Sun Studio in der Regel, da es insbesondere auf Sparc-Systemen häufig bessere Ergebnisse liefert. Open Source-Projekte werden jedoch mit gcc-spezifischem Code geschrieben. Es kann ziemlich schmerzhaft sein, wenn jemand zusammenarbeitet.


0

C ist wahrscheinlich C ++ vorzuziehen, wenn der C-Code generiert wird (z. B. in Implementierungen von höheren Sprachen). Zum Beispiel gibt es mehrere Lisp-ähnliche Compiler, die C-Code ausgeben (z. B. Chicken , Scheme48 ...), aber ich kenne keinen, der echten C ++ - Code ausgibt (mein MELT- Tool gibt C ++ - Code aus, aber ich bezeichne diesen Code nicht als echt C ++ - Code, es werden nur sehr wenige C ++ - Funktionen verwendet.

C-Code lässt sich auch leichter halbautomatisch beweisen. Statische Analysatoren wie Frama-C (bei denen Sie Ihren C-Code mit ACSL-Kommentaren versehen, um den Beweisgrund für Ihren Code zu ermitteln) sind für C verfügbar, für C ++ 11 jedoch nicht so häufig.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.