Ist es notwendig, den Standard zu befolgen, für diese Angelegenheit den C-Standard zu nehmen?

17

Es gibt einige sehr erfahrene Leute bei Stack Overflow, die immer über den C-Standard sprechen. Die Leute scheinen nicht tragbare Lösungen nicht zu mögen, auch wenn sie für mich arbeiten. Ok, ich verstehe, dass der Standard befolgt werden muss, aber schränkt er nicht die Kreativität des Programmierers ein?

Welche konkreten Vorteile ergeben sich aus der Einhaltung einer Norm? Zumal Compiler den Standard möglicherweise etwas anders implementieren.

0decimal0
quelle
7
Können Sie klarstellen, was Sie unter "Standard" verstehen? Meinen Sie damit, nicht auf Verhalten zu reagieren, das nicht durch die Norm definiert ist? Oder nicht mit Erweiterungen / Compiler-Funktionen? Oder Stilkonventionen?
ikh
1
@ikh Er nimmt etwa ISO C-Standards (C90, C99, C11).
Aseem Bansal
9
Das ist das Gleiche wie zu sagen, dass das Schreiben oder Sprechen in englischer Sprache unter Verwendung der englischen Grammatik und des englischen Wortschatzes Ihrer Kreativität Fesseln setzt. Sicher, Menschen können wundervolle Dinge tun, indem sie gegen die Regeln verstoßen, auf Kosten der Kohärenz, aber Sie können Millionen von kreativen Büchern schreiben, während Sie immer noch den "Standard" des Englischen einhalten.
Avner Shahar-Kashtan
Können Sie ein Beispiel hinzufügen für "Die Leute scheinen nicht tragbare Lösungen nicht zu mögen, auch wenn sie für mich arbeiten"?
BЈовић
1
@PHIfounder Nur um diesen letzten Fall zu behandeln, können Sie die Rückkehr von main weglassen, es ist implizit die Rückkehr 0 :)
Daniel Gratzer

Antworten:

45

Es gibt einige Gründe, warum das Festhalten am Standard eine gute Sache ist.

  1. In einen Compiler gesperrt zu sein, ist zum Kotzen. Sie sind einer Gruppe von Entwicklern mit eigener Agenda völlig ausgeliefert. Sie sind offensichtlich nicht auf der Suche nach Ihnen oder etwas anderem, aber wenn Ihr Compiler anfängt, Optimierungen, neue Funktionen, Sicherheitsverbesserungen usw. in den Hintergrund zu rücken, ist dies zu schade. Du steckst fest. In extremen Fällen müssen einige Unternehmen mit dem Patchen des Tools beginnen, von dem sie sich abhängig gemacht haben. Dies ist eine enorme Geld- und Zeitverschwendung, wenn es andere Arbeitsinstrumente gibt.

  2. Auf einer Plattform eingesperrt zu sein, ist schwerer. Wenn Sie Software auf Linux pushen und auf Windows umsteigen möchten, weil Sie erkennen, dass Ihr Markt wirklich da ist, müssen Sie verdammt schnell jeden nicht portablen Hack ändern, den Sie in Ihrem Code haben, um gut zu spielen mit GCC und MSVC. Wenn Sie mehrere Teile Ihres Kerndesigns haben, die auf so etwas basieren, viel Glück!

  3. Rückwärts inkompatible Änderungen sind am härtesten. Der Standard wird niemals Ihren Code brechen (Python ignorieren). Einige zufällige Compiler-Autoren könnten jedoch entscheiden, dass dieses implementierungsspezifische Add-On den Aufwand nicht wert ist, und es fallen lassen. Wenn Sie sich zufällig darauf verlassen, bleiben Sie bei der alten veralteten Version hängen, in der sie zuletzt verwendet wurde.

Die übergeordnete Botschaft, sich an den Standard zu halten, macht Sie flexibler . Sie haben sicher eine eingeschränkte Sprache, aber Sie haben mehr

  • Bibliotheken
  • Support (die Leute kennen den Standard, nicht jeden komplizierten compilerspezifischen Hack)
  • Verfügbare Plattformen
  • Ausgereifte Werkzeuge
  • Sicherheit (Zukunftssicherheit)

Es ist ein heikles Gleichgewicht, aber das völlige Ignorieren des Standards ist definitiv ein Fehler. Ich neige dazu, meinen C-Code so zu organisieren, dass er sich auf Abstraktionen stützt, die möglicherweise nicht portierbar sind, aber transparent portiert werden können, ohne alles zu ändern, was von der Abstraktion abhängt.

Daniel Gratzer
quelle
+1 fair genug :), danke ... Ich war ernsthaft verwirrt darüber, wie Compiler geringfügig von den Standards abweichten, und fühlte mich skeptisch, wenn es darum ging, sie genau zu befolgen. Ich musste die Vor- und Nachteile kennen und Sie identifizierten sie eindeutig.
0decimal0
6
Undefiniertes Verhalten ist wahrscheinlich auch ziemlich zum Kotzen. Mit c ist es ziemlich einfach, sich in UB zu wagen, wenn Sie dem Standard nicht genau folgen.
CodesInChaos
@CodesInChaos Einigermaßen undefiniertes Verhalten ist zum einen großartig, da es einige verrückte Optimierungen zulässt, zum anderen aber das Debuggen ...
Daniel Gratzer
6

Der Standard ist eine Art "Vertrag" zwischen Ihnen und Ihrem Compiler, der die Bedeutung Ihrer Programme definiert. Als Programmierer haben wir oft ein bestimmtes mentales Modell, wie die Sprache funktioniert, und dieses mentale Modell steht oft im Widerspruch zum Standard. (C-Programmierer stellen sich einen Zeiger beispielsweise häufig grob als "eine Ganzzahl, die eine Speicheradresse angibt" vor und gehen daher davon aus, dass es sicher ist, Arithmetik / Konvertierungen / Manipulationen an Zeigern durchzuführen, die mit einer Ganzzahl ausgeführt werden, die einen Speicher angibt Diese Annahme stimmt nicht mit dem Standard überein, sondern schränkt die Möglichkeiten mit Zeigern sehr stark ein.)

Was ist also der Vorteil, dem Standard zu folgen, anstatt Ihrem eigenen mentalen Modell zu folgen?

Einfach ausgedrückt, der Standard ist korrekt und Ihr eigenes mentales Modell ist falsch. Ihr mentales Modell ist in der Regel eine vereinfachte Ansicht der Funktionsweise auf Ihrem eigenen System, wobei in den meisten Fällen alle Compiler-Optimierungen deaktiviert sind. Compiler-Hersteller bemühen sich im Allgemeinen nicht, sich daran anzupassen, insbesondere wenn es um Optimierungen geht. (Wenn Sie Ihr Vertragsende nicht aufhalten, können Sie vom Compiler kein bestimmtes Verhalten erwarten: Garbage-In, Garbage-Out.)

Die Leute scheinen nicht tragbare Lösungen nicht zu mögen, auch wenn sie für mich arbeiten.

Es könnte besser sein zu sagen, "auch wenn sie für mich zu arbeiten scheinen ". Wenn Ihr Compiler nicht ausdrücklich dokumentiert, dass ein bestimmtes Verhalten funktioniert (dh, wenn Sie keinen angereicherten Standard verwenden, der aus der richtigen Standard- und Compiler-Dokumentation besteht), wissen Sie nicht, dass es wirklich funktioniert oder dass es wirklich zuverlässig ist. Beispielsweise führt der Überlauf von Ganzzahlen mit Vorzeichen in der Regel auf vielen Systemen zu einem Zeilenumbruch ( INT_MAX+1was normalerweise der Fall ist INT_MIN) - außer dass Compiler "wissen", dass Arithmetik mit Ganzzahlen mit Vorzeichen in einem (korrekten) C-Programm niemals überläuft, und auf dieser Grundlage häufig sehr überraschende Optimierungen durchführen. " Wissen".

ruakh
quelle
1
Sie könnten mit -fwrapveiner etwas anderen, nicht standardmäßigen Sprache kompilieren und dann verwenden, bei der die vorzeichenbehaftete Ganzzahl-Arithmetik immer umbrochen wird.
user253751
@immibis: Als C89 geschrieben wurde, definierte die Mehrheit der zeitgenössischen Compiler laut seinem Grundlagendokument eine Semantik für das stille Umschließen für einen Ganzzahlüberlauf. In vielen Fällen kann das Vorhandensein einiger Garantien dafür, was bei einem Ganzzahlüberlauf passiert, zu einer höheren Effizienz des Codes führen, als dies ohne solche Garantien möglich wäre, insbesondere wenn die Garantien kein genaues Umbruchverhalten vorschreiben [präzise] Das Umbruchverhalten könnte mit vorzeichenloser Mathematik emuliert werden, aber eine Semantik, die zwar lockerer ist, aber dennoch den Anforderungen entspricht, kann effizienteren Code ermöglichen.
Supercat
@immibis: Es ist schade, dass Revisionisten die Leute davon überzeugen konnten, dass Verhaltensweisen, die bei Compilern für bestimmte Plattformen fast einstimmig (oder in einigen Fällen zu 100% einstimmig) implementiert wurden, auf solchen Plattformen nie "Standard" waren, da in vielen Fällen die Effizienzverluste, die sich aus der Vermeidung solcher Verhaltensweisen ergeben, werden durch keine "Optimierungen" kompensiert, die ein Compiler durch Widerruf erreichen konnte.
Supercat
4

Ich verstehe, dass der Standard befolgt werden muss, aber belastet er nicht die Kreativität des Programmierers? Es gibt immer noch einige Unterschiede in der Art und Weise, wie verschiedene Compiler den Standards folgen. Ich kann zum Beispiel einen Code schreiben, der funktioniert, sehr gut in Leistung und Geschwindigkeit, das heißt, alles, was zählt, aber das muss nicht unbedingt genau den Standards entsprechen.

Nein. Der Standard gibt an, was zu tun ist. Wenn es nicht spezifiziert ist, befinden Sie sich in einem undefinierten Verhaltensgebiet und dann sind alle Wetten aus - das Programm kann alles tun.


Da Sie ein konkretes Beispiel für void main()vs erwähnt haben int main(), kann ich meine Antwort verbessern.

void main()ist keine Standarddeklaration der Hauptfunktion. Es kann auf einigen Compilern über Erweiterungen funktionieren, hängt jedoch von der Implementierung ab. Auch wenn es funktioniert, müssen Sie überprüfen, ob es das tut, was Sie wollen. Das Problem ist, dass Compiler-Entwickler möglicherweise entscheiden, es void main()mit der nächsten Compiler-Version zu entfernen , wodurch Ihre Anwendung beschädigt wird.

Andererseits definiert der Standard die Signatur von main as klar int main()und gibt an, was zu tun ist.


Andererseits gibt es Dinge, die in der Norm nicht definiert sind. Dann kann ein anderer Standard gelten (wie zum Beispiel POSIX). Das beste Beispiel könnte die Implementierung von Threads in c ++ 03 sein, da c ++ 03-Standardprogramme 1-Thread-Programme waren. In diesem Fall müssen Sie eine plattformabhängige Bibliothek oder eine Art Boost verwenden .

BЈовић
quelle
4
Alles, was ein Compiler macht, das kein Standard ist, ist kein undefiniertes Verhalten. Compilererweiterungen sind in dem Sinne gut definiert, dass sie deterministisch und absichtlich sind. UB nicht.
Daniel Gratzer
@jozefg Die Art und Weise, wie es gefragt wurde - es ist offensichtlich, dass das OP von UB Art und Weise der Umsetzung gedacht. Beispielsweise wurden in c ++ 03 keine Threads definiert.
BЈовић
1
@deworde: Der Kommentar wurde aus der Antwort entfernt.
Kevin - Reinstate Monica
@jozefg Wenn ein bestimmter Compiler immer vorzeichenbehaftete Ganzzahlen umschließt, kann dies als undokumentierte Spracherweiterung angesehen werden. (
Undokumentiert zu sein
-6

Befolgen Sie keine Regeln, wenn es sich bei Ihrem Projekt um spezielle Projekte handelt, zum Beispiel um ein Regierungsprojekt oder ein Armeeprojekt. Sie müssen jedoch Regeln befolgen, wenn es sich um ein Open Source- oder großes Projekt mit einem verteilten Team handelt.

Unbekannt
quelle
2
Ohne eine Erklärung kann diese Antwort für den Fall unbrauchbar werden, dass jemand anders eine gegenteilige Meinung äußert. Wenn zum Beispiel jemand eine Behauptung aufstellt wie "Befolgen Sie Regeln, WENN es sich bei Ihrem Projekt um spezielle Projekte handelt, zum Beispiel um ein Regierungsprojekt oder ein Armee-Projekt, aber Sie müssen keine Regeln befolgen, WENN es sich um Open Source handelt ..." , wie würde diese Antwort dem Leser helfen, zwei gegensätzliche Meinungen zu treffen? Überlegen Sie , ob Sie es in eine bessere Form bringen
möchten
2
Unbekannt: Es würde Sie überraschen, wie viele Standards in Regierungsprojekten vorhanden sind ...
Deer Hunter