2016-04-21 1 views
10

Dies ist eher eine Frage über den Programmierstil als über Technizität: Sollte meine C-Funktion immer ein Argument für die Länge eines Arrays benötigen, obwohl die Funktion nicht davon abhängig ist?Sollte die aufgerufene Funktion immer die Array-Größe in C überprüfen?

Also entweder wie diese void foo(int* a, int size) oder wie void foo(int* a)

Z.B. Wenn die Funktion nur die ersten 128 Bits des Arrays manipuliert, sollte die Funktion eine Array - Länge benötigen und zuerst prüfen, ob das Array die richtige Länge hat oder ob ich dem Aufrufer traue, dass er der Dokumentation folgt und nur die Funktion mit dem Aufruf aufruft richtige Größe des Arrays?

Ich bin neu in C, also befürchte ich, dass so etwas wie ein Pufferüberlauf möglich ist. Eine technische Begründung dafür, warum man besser ist als die andere, wäre großartig. Vielen Dank!

+0

Nicht zwingend, aber wenn Sie dies tun, wird Ihre Funktion mehr _modular_ sein. –

+2

Vertraue niemals blindlings Programmierern, das zu tun, was sie tun sollten, also ja; Sie sollten immer eine Länge in dieser Art von Funktionen hinzufügen. – Sander

+2

Nehmen Sie die Funktionen in der C-Bibliothek als gute Beispiele. Sie bieten beide Ansätze (wie 'strcmp'vs.' Strncmp'). Im Allgemeinen lautet die Philosophie von C: "Wenn man weiß, dass der Programmierer weiß, was er tut, hat seinen Preis, nehme an, dass er es ist." und "lass den Programmierer entscheiden". – tofro

Antwort

15

Meine Regel ist, zwischen Schnittstellenpunkten und internen Funktionen zu unterscheiden. Schnittstellenfunktionen müssen paranoid und robust sein, aber interne Funktionen können davon ausgehen, dass der Anrufer weiß, was er tut, und sich für Effizienz gegenüber Robustheit entscheiden können.

3

Eine allgemeine Regel sollte sein, um Fehler so schnell wie möglich bekannt zu machen. Sie können einen Fehler zur Kompilierzeit, zur Verbindungszeit oder zur Ausführungszeit erhalten oder nie abgefangen werden und ein undefiniertes Verhalten haben.

Da Sie die Größe überprüfen und einen Laufzeitfehler erzeugen können, würde ich sagen, dass es besser ist als ein undefiniertes Verhalten, wenn ein Benutzer Ihrer Funktion ein kleineres Array übergibt.

Natürlich ist Geschwindigkeit manchmal wichtiger und das Extra, wenn nicht gewünscht wird, dann müssen Sie mitteilen, dass Ihre Benutzer die Dokumentation lesen werden. So werden viele Standard-Bibliotheksfunktionen geschrieben. Aber das sollte Randfälle in Ihrem Programm sein. Im Allgemeinen bevorzugen Sie, Fehler zu finden, so dass Sie weniger Fehler in Ihrem Code haben.

+0

_ "Eine allgemeine Regel sollte darin bestehen, Fehler so schnell wie möglich bekannt zu machen." _ - Ich bin ziemlich überrascht, _this_ in einem C-Thread zu sehen. Scheint nicht gut zusammen mit der C-Design-Philosophie zu sein. – emlai

+0

@tuple_cat Am Anfang hatte die Frage ein C++ - Tag :) – rozina

+0

@tuple_cat "Scheint nicht gut zusammen mit der C-Design-Philosophie zu gehen." - Ich würde gerne hören warum. Ich wusste nicht, dass C in dieser Hinsicht spezifisch ist. – rozina

1

Ich werde es so sagen, wie Souvrav sagte, es ist nicht obligatorisch, was bedeutet, dass wenn Sie 100% sicher sind, dass die Länge "richtig" ist, können Sie den Scheck überspringen, aber es wird nicht empfohlen, auch wenn Sie 120 sind % sicher, dass kein Überlauf auftritt. Wenn Sie diese Überprüfung hinzufügen, wird die Funktion auch für Fälle verwendet, in denen Sie sich nicht sicher sind, wie lange sie sind. Daher ist es besser, sie einfach hinzuzufügen, auch wenn Sie sie nicht benötigen.

2

Kurze Antwort: Ja, Sie sollten. : D Lange Antwort: Da Ihr Array tatsächlich ein Speicherzeiger ist, können Sie nicht einfach die tatsächliche Größe davon erhalten. Wenn also Ihre Funktion die Array-Daten ändern soll, sollten Sie überprüfen, ob sie dies tatsächlich tun können, ohne Speicher zu überschreiben, der nicht Ihrem Array zugewiesen ist. Es empfiehlt sich in der Regel, Speichergrenzen zu überprüfen, bevor Daten in einen Zeiger geschrieben werden. ;)

+1

[wieder gelöscht Kommentar] in der Tat, mit nur einem Zeiger ist es nicht "kann nicht leicht": Sie können einfach nicht die Größe der entsprechenden Zuordnung wissen. (Jemand könnte sagen, dass Sie die Art und Weise nutzen können, wie Ihr Betriebssystem diese Informationen verfolgt, aber das ist bestenfalls ein gefährlicher Hack) –

3

Gute Frage, weil Sie versuchen, die Absicht hinter dem Programmierstil/-ansatz zu verstehen, bevor Sie ihn blind benutzen.

Lassen Sie mich Ihnen meine Perspektive geben. Ein Code gilt als gesund, wenn er dem folgenden entspricht.

  • Wenn Sie lesen können & den Code verstehen, ohne die Notwendigkeit von Kommentaren.
  • Wenn Ihr Code leicht für zukünftige Wartungstechniker ohne große Schwierigkeiten beibehalten werden kann.
  • Wenn Sie Erweiterungen zum ursprünglichen Code hinzufügen können, ohne den ursprünglichen Code drastisch zu ändern
  • Wenn Ihr Code für die Änderungen in der Menge der Eingaben geschlossen/unbeeinträchtigt ist, dh Ihr Code löst alle verschiedenen Varianten desselben Verwendungszwecks Fall. Bitte beziehen Sie sich auf Open/Closed principle.
  • Die Idee, die Länge in die Funktionssignatur einzubeziehen, fällt auf die ersten beiden Aufzählungszeichen.

    Als Autor einer Funktion/Logik wissen Sie genau, was Sie erreichen werden und daher möchten Sie nicht die Länge hinzufügen. Denken Sie jedoch an den Fall, einige Zeit später kommt ein Fehler, und Sie sind nicht mehr in dem Projekt und jemand anderes übernimmt die Rolle der Wartung. Es wird beträchtliche Anstrengungen für den Ingenieur brauchen, um einen Sinn dessen zu entwickeln, was Sie geschrieben haben, und den Fehler zu beheben.

    Während einige argumentieren, dass sie Kommentare schreiben/haben eine Low-Level-Dokumentation usw., ist es nicht immer eine praktikable Lösung. Der richtige Weg besteht darin, einem Programmierstil zu folgen, der die Code-Überprüfung intuitiv macht und zukünftigen Entwicklern hilft, leicht zum Projekt beizutragen.

    Zusammengefasst, Nein, es ist nicht obligatorisch, eine Länge anzugeben, aber es wird immer empfohlen, gute Codierungsrichtlinien zu befolgen, um ein gutes Ökosystem zu fördern.

    Wenn Sie möchten, zu einem der Open-Source-Projekt beitragen, dann sollten Sie dieses Konzept sicher umarmen :-)

    Good Luck!

    +0

    "Der Begriff der Länge in der Funktionssignatur fällt auf die ersten beiden Aufzählungspunkte." - stimme entschieden nicht zu. Ich bemerke, dass du nicht erklärt hast, warum gerade eine Reihe von Plattitüden abgespult wurde, die nichts wirklich sagen.Also, warum denkst du, dass die Einbeziehung der Größe (A) Menschen "nicht in die Lage versetzt, den Code zu lesen und zu verstehen" und (B) den Code nicht "ohne große Schwierigkeiten" wartbar macht? –

    +0

    Der Zweck des Hinzufügens der Länge ist es, bestimmte Fehlerszenarien zu erfassen und bestimmte Fehlerszenarien zu vermeiden. Zu der Zeit wollte ich denen antworten, ich sah die schon beantwortet. Anstatt also den gleichen Punkt zu zitieren, wollte ich nur eine andere Perspektive einer gesunden Kodierung geben. –

    +0

    Angenommen, der Autor hat die Länge nicht explizit angegeben und der Code innerhalb der Funktion arbeitet mit der magischen Zahl 128/MACRO und nimmt an, dass der Aufrufer und der Aufrufer Teil einer anderen Komponente sind, die anders gepflegt wird. Dann könnte er für zukünftige Entwickler der magischen Zahl 128 skeptisch gegenüberstehen. Hier kommt der Teil der Wartbarkeit ins Spiel. –

    1

    Da dies C ist, sollten Sie "dem Programmierer vertrauen".

    Es gibt keine Möglichkeit sicherzustellen, dass der size Parameter die tatsächliche Länge des Arrays ist. Es könnte eine beliebige Zahl sein. Warum also stören (und die Oberfläche durcheinander bringen) (und das Programm verlangsamen)?

    +0

    Ich bin nicht einverstanden mit Ihnen, aber einige Branchen wie Automotive, Aerospace & Verteidigung bestehen auf C und nicht "vertrauen" C++ – Mawg

    +1

    C kann sicher sein. Du musst es nicht sicher machen, wenn du es nicht willst, aber lass es uns nicht implizieren, dass es von Natur aus sicher ist. Ein guter Programmierer kann es so machen. Ich denke, C++ ist großartig, aber ich denke auch, dass Sie hier aus Ihren eigenen Vorurteilen extrapolieren. –

    +2

    C kann in einem bestimmten Kontext sicher sein, aber in diesem speziellen Fall gibt es keine Möglichkeit sicherzustellen, dass der Parameter "length" die tatsächliche Länge des Arrays ist. Es könnte eine beliebige Zahl sein. Es gibt absolut keine Möglichkeit, sicherzustellen, dass ein Array-Parameter eine bestimmte Länge hat. Ich sehe nicht, dass das nicht von Natur aus unsicher ist. – emlai

    Verwandte Themen