Warum ist die get-Funktion so gefährlich, dass sie nicht verwendet werden sollte?


228

Wenn ich versuche, C-Code zu kompilieren, der die gets()Funktion mit GCC verwendet, wird folgende Warnung angezeigt:

(.text + 0x34): Warnung: Die Funktion "get" ist gefährlich und sollte nicht verwendet werden.

Ich erinnere mich, dass dies etwas mit Stapelschutz und Sicherheit zu tun hat, aber ich weiß nicht genau warum.

Wie kann ich diese Warnung entfernen und warum gibt es eine solche Warnung zur Verwendung gets()?

Wenn gets()es so gefährlich ist, warum können wir es dann nicht entfernen?



Antworten:


178

Um getssicher zu verwenden , müssen Sie genau wissen, wie viele Zeichen Sie lesen werden, damit Sie Ihren Puffer groß genug machen können. Sie werden das nur wissen, wenn Sie genau wissen, welche Daten Sie lesen werden.

Anstatt zu verwenden gets, möchten Sie verwenden fgets, die die Signatur hat

char* fgets(char *string, int length, FILE * stream);

( fgetsWenn es eine ganze Zeile liest, bleibt das '\n'in der Zeichenfolge; Sie müssen sich darum kümmern.)

Es blieb ein offizieller Teil der Sprache bis zur ISO C-Norm von 1999, wurde jedoch durch die Norm von 2011 offiziell entfernt. Die meisten C-Implementierungen unterstützen es weiterhin, aber zumindest gibt gcc eine Warnung für jeden Code aus, der es verwendet.


79
Es ist eigentlich nicht gcc, das warnt, sondern das glibc, das ein Pragma oder Attribut enthält gets(), das den Compiler veranlasst, bei Verwendung eine Warnung auszugeben.
Fuz

@fuz eigentlich warnt nicht einmal der Compiler: Die im OP zitierte Warnung wurde vom Linker gedruckt!
Ruslan

161

Warum ist gets()gefährlich

Der erste Internet-Wurm (der Morris-Internet-Wurm ) ist vor etwa 30 Jahren (1988-11-02) entkommen gets()und hat einen Pufferüberlauf als eine seiner Methoden zur Ausbreitung von System zu System verwendet. Das Grundproblem besteht darin, dass die Funktion nicht weiß, wie groß der Puffer ist. Daher liest sie weiter, bis sie eine neue Zeile findet oder auf EOF stößt und möglicherweise die Grenzen des Puffers überschreitet, den sie erhalten hat.

Sie sollten vergessen, dass Sie jemals gehört haben, dass gets()es das gibt.

Die C11-Norm ISO / IEC 9899: 2011 wurde gets()als Standardfunktion gestrichen. Dies ist A Good Thing ™ (sie wurde in ISO / IEC 9899: 1999 / Cor.3: 2007 - Technische Berichtigung offiziell als „veraltet“ und „veraltet“ gekennzeichnet 3 für C99 und dann in C11 entfernt). Leider wird es aus Gründen der Abwärtskompatibilität viele Jahre (dh "Jahrzehnte") in Bibliotheken verbleiben. Wenn es nach mir gets()ginge, würde die Implementierung von :

char *gets(char *buffer)
{
    assert(buffer != 0);
    abort();
    return 0;
}

Da Ihr Code früher oder später ohnehin abstürzt, ist es besser, die Probleme eher früher als später zu lösen. Ich wäre bereit, eine Fehlermeldung hinzuzufügen:

fputs("obsolete and dangerous function gets() called\n", stderr);

Moderne Versionen des Linux-Kompilierungssystems generieren Warnungen, wenn Sie eine Verknüpfung herstellen gets()- und auch für einige andere Funktionen, bei denen ebenfalls Sicherheitsprobleme auftreten ( mktemp(),…).

Alternativen zu gets()

fgets ()

Wie alle anderen sagten, besteht die kanonische Alternative dazu gets()darin fgets(), stdinals Dateistream anzugeben .

char buffer[BUFSIZ];

while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
    ...process line of data...
}

Was noch niemand erwähnt hat, ist, dass gets()es die Newline nicht enthält, aber fgets()tut. Daher müssen Sie möglicherweise einen Wrapper verwenden fgets(), der die neue Zeile löscht:

char *fgets_wrapper(char *buffer, size_t buflen, FILE *fp)
{
    if (fgets(buffer, buflen, fp) != 0)
    {
        size_t len = strlen(buffer);
        if (len > 0 && buffer[len-1] == '\n')
            buffer[len-1] = '\0';
        return buffer;
    }
    return 0;
}

Oder besser:

char *fgets_wrapper(char *buffer, size_t buflen, FILE *fp)
{
    if (fgets(buffer, buflen, fp) != 0)
    {
        buffer[strcspn(buffer, "\n")] = '\0';
        return buffer;
    }
    return 0;
}

Auch als caf Punkte in einem Kommentar und aus paxdiablo zeigt in seiner Antwort mit fgets()Ihnen Daten auf einer Linie übrig haben könnten. Mein Wrapper-Code lässt diese Daten beim nächsten Mal gelesen werden. Sie können es leicht ändern, um den Rest der Datenzeile zu verschlingen, wenn Sie es vorziehen:

        if (len > 0 && buffer[len-1] == '\n')
            buffer[len-1] = '\0';
        else
        {
             int ch;
             while ((ch = getc(fp)) != EOF && ch != '\n')
                 ;
        }

Das verbleibende Problem besteht darin, wie die drei verschiedenen Ergebniszustände gemeldet werden - EOF oder Fehler, Zeilen lesen und nicht abgeschnitten und Teilzeile lesen, aber Daten wurden abgeschnitten.

Dieses Problem tritt nicht auf, gets()weil es nicht weiß, wo Ihr Puffer endet und fröhlich über das Ende hinaus trampelt, was Ihr wunderschön gepflegtes Speicherlayout verwüstet und häufig den Rückgabestapel (einen Stapelüberlauf) durcheinander bringt, wenn der Puffer zugewiesen ist den Stapel oder das Trampeln über die Steuerinformationen, wenn der Puffer dynamisch zugewiesen ist, oder das Kopieren von Daten über andere wertvolle globale (oder Modul-) Variablen, wenn der Puffer statisch zugewiesen ist. Nichts davon ist eine gute Idee - sie verkörpern den Ausdruck "undefiniertes Verhalten".


Es gibt auch den TR 24731-1 (Technischer Bericht des C-Standardausschusses), der sicherere Alternativen zu einer Vielzahl von Funktionen bietet, darunter gets():

§6.5.4.1 Die gets_sFunktion

Zusammenfassung

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
char *gets_s(char *s, rsize_t n);

Laufzeitbeschränkungen

sdarf kein Nullzeiger sein. ndarf weder gleich Null noch größer als RSIZE_MAX sein. Beim Lesen von n-1Zeichen aus muss ein Zeichen für eine neue Zeile, ein Dateiende oder ein Lesefehler auftreten stdin. 25)

3 Wenn eine Laufzeitbeschränkungsverletzung vorliegt, s[0]wird diese auf das Nullzeichen gesetzt und die Zeichen werden gelesen und verworfen, stdinbis ein Zeichen in einer neuen Zeile gelesen wird oder ein Dateiende oder ein Lesefehler auftritt.

Beschreibung

4 Die gets_sFunktion liest höchstens eins weniger als die Anzahl der Zeichen, die von angegeben sind, n aus dem Stream, auf den von zeigt stdin, in das Array, auf das von gezeigt wird s. Nach einem neuen Zeilenzeichen (das verworfen wird) oder nach dem Dateiende werden keine zusätzlichen Zeichen gelesen. Das verworfene neue Zeilenzeichen zählt nicht für die Anzahl der gelesenen Zeichen. Ein Nullzeichen wird unmittelbar nach dem letzten in das Array eingelesenen Zeichen geschrieben.

5 Wenn das Dateiende festgestellt wird und keine Zeichen in das Array eingelesen wurden oder wenn während des Vorgangs ein Lesefehler auftritt, s[0]wird das Zeichen Null gesetzt und die anderen Elemente von snehmen nicht angegebene Werte an.

Empfohlene Praxis

6 Mit dieser fgetsFunktion können ordnungsgemäß geschriebene Programme Eingabezeilen sicher verarbeiten, die zu lang sind, um sie im Ergebnisarray zu speichern. Im Allgemeinen erfordert dies, dass Anrufer fgetsauf das Vorhandensein oder Fehlen eines neuen Zeilenzeichens im Ergebnisarray achten. Erwägen Sie die Verwendung fgets(zusammen mit der erforderlichen Verarbeitung basierend auf Zeichen in neuen Zeilen) anstelle von gets_s.

25) Im gets_sGegensatz dazu getsmacht die Funktion es zu einer Verletzung der Laufzeitbeschränkung für eine Eingabezeile, um den Puffer zum Speichern zu überlaufen. Im Gegensatz dazu fgetswird gets_seine Eins-zu-Eins-Beziehung zwischen Eingabezeilen und erfolgreichen Aufrufen von beibehalten gets_s. Programme, die verwenden, getserwarten eine solche Beziehung.

Die Microsoft Visual Studio-Compiler implementieren eine Annäherung an den TR 24731-1-Standard, es gibt jedoch Unterschiede zwischen den von Microsoft implementierten Signaturen und denen im TR.

Die C11-Norm ISO / IEC 9899-2011 enthält TR24731 in Anhang K als optionalen Teil der Bibliothek. Leider wird es auf Unix-ähnlichen Systemen selten implementiert.


getline() - POSIX

POSIX 2008 bietet auch eine sichere Alternative zu gets()aufgerufen getline(). Es weist der Zeile dynamisch Speicherplatz zu, sodass Sie sie am Ende freigeben müssen. Dadurch wird die Beschränkung der Zeilenlänge aufgehoben. Es gibt auch die Länge der gelesenen Daten zurück oder -1(und nicht EOF!), Was bedeutet, dass Null-Bytes in der Eingabe zuverlässig verarbeitet werden können. Es gibt auch eine ‚wählen Sie Ihre eigenen Einzel Zeichenbegrenzer‘ Variation genannt getdelim(); Dies kann nützlich sein, wenn Sie sich mit der Ausgabe befassen, bei der find -print0die Enden der Dateinamen beispielsweise mit einem ASCII-NUL- '\0'Zeichen markiert sind .


8
Es ist auch erwähnenswert, dass fgets()Ihre fgets_wrapper()Version den nachfolgenden Teil einer überlangen Zeile im Eingabepuffer belässt, um von der nächsten Eingabefunktion gelesen zu werden. In vielen Fällen möchten Sie diese Zeichen lesen und verwerfen.
Café

5
Ich frage mich, warum sie keine fgets () -Alternative hinzugefügt haben, mit der man ihre Funktionalität nutzen kann, ohne einen dummen Strlen-Aufruf tätigen zu müssen. Beispielsweise würde eine fgets-Variante, die die Anzahl der in die Zeichenfolge gelesenen Bytes zurückgibt, dem Code das Erkennen erleichtern, ob das zuletzt gelesene Byte eine neue Zeile war. Wenn das Verhalten beim Übergeben eines Nullzeigers für den Puffer als "Lesen und Verwerfen von bis zu n-1 Bytes bis zur nächsten neuen Zeile" definiert würde, würde dies dem Code ermöglichen, das Ende von überlangen Zeilen leicht zu verwerfen.
Supercat

2
@supercat: Ja, ich stimme zu - es ist schade. Der nächstgelegene Ansatz dazu ist wahrscheinlich POSIX getline()und sein Verwandter getdelim(), die die Länge der von den Befehlen gelesenen 'Zeile' zurückgeben und nach Bedarf Speicherplatz zuweisen, um die gesamte Zeile speichern zu können. Selbst das kann zu Problemen führen, wenn Sie eine einzeilige JSON-Datei mit einer Größe von mehreren Gigabyte erhalten. Kannst du dir all diese Erinnerung leisten? (Und wenn wir schon dabei sind, können wir haben strcpy()und strcat()Varianten , die einen Zeiger auf das Null - Byte am Ende zurückkehren Etc.?)
Jonathan Leffler

4
@supercat: Das andere Problem fgets()ist, dass wenn die Datei ein Null-Byte enthält, Sie nicht sagen können, wie viele Daten nach dem Null-Byte bis zum Zeilenende (oder EOF) vorhanden sind. strlen()kann nur bis zum Null-Byte in den Daten melden; danach ist es Vermutung und daher mit ziemlicher Sicherheit falsch.
Jonathan Leffler

7
"Vergiss, dass du jemals gehört hast, dass gets()es das gibt." Wenn ich das mache, stoße ich wieder darauf und komme hierher zurück. Hacken Sie Stackoverflow, um Upvotes zu erhalten?
candied_orange

21

Weil getses keine Überprüfung durchführt, während Bytes von stdin abgerufen und irgendwo abgelegt werden. Ein einfaches Beispiel:

char array1[] = "12345";
char array2[] = "67890";

gets(array1);

Zunächst dürfen Sie eingeben, wie viele Zeichen Sie möchten, getsohne sich darum zu kümmern. Zweitens array1überschreiben die Bytes über der Größe des Arrays, in das Sie sie eingefügt haben (in diesem Fall ), alles, was sie im Speicher finden, weil getssie geschrieben werden. Im vorherigen Beispiel bedeutet dies, dass bei einer "abcdefghijklmnopqrts"unvorhersehbaren Eingabe auch array2oder was auch immer überschrieben wird .

Die Funktion ist unsicher, da sie eine konsistente Eingabe voraussetzt. NIEMALS VERWENDEN!


3
Was getsvöllig unbrauchbar macht , ist, dass es keinen Parameter für die Länge / Anzahl des Arrays gibt, den es braucht. Wäre es dort gewesen, wäre es nur eine andere gewöhnliche C-Standardfunktion.
Legends2k

@ legends2k: Ich bin gespannt, wofür die beabsichtigte Verwendung getswar und warum keine Standard-Fgets-Variante für Anwendungsfälle so praktisch gemacht wurde, in denen der Zeilenumbruch nicht als Teil der Eingabe gewünscht wird.
Supercat

1
@supercat getswar, wie der Name schon sagt, entworfen von einer Zeichenfolge zu bekommen stdin, aber die Gründe für nicht mit Größe Parameter kann aus gewesen sein Geist von C : der Programmierer Trust. Diese Funktion wurde in C11 entfernt und die angegebene Ersetzung gets_snimmt die Größe des Eingabepuffers an. Ich habe jedoch keine Ahnung von dem fgetsTeil.
Legends2k

@ legends2k: Der einzige Kontext, den ich sehen kann gets, der entschuldbar sein könnte, wäre, wenn man ein Hardware-Zeilen-gepuffertes E / A-System verwendet, das physisch nicht in der Lage ist, eine Zeile über eine bestimmte Länge und die beabsichtigte Lebensdauer des Programms zu senden war kürzer als die Lebensdauer der Hardware. In diesem Fall könnte es gerechtfertigt sein, wenn Hardware nicht in der Lage ist, Leitungen mit einer Länge von mehr als 127 Byte zu senden, getsin einen 128-Byte-Puffer zu wechseln, obwohl ich denke, dass die Vorteile der Angabe eines kürzeren Puffers bei der Erwartung kleinerer Eingaben dies mehr als rechtfertigen würden kosten.
Supercat

@ legends2k: Eigentlich wäre es ideal gewesen, wenn ein "String-Zeiger" ein Byte identifiziert hätte, das aus einigen verschiedenen String- / Puffer- / Puffer-Info-Formaten auswählen würde, wobei ein Wert des Präfix-Bytes eine enthaltene Struktur angibt das Präfixbyte [plus Auffüllen] sowie die Puffergröße, die verwendete Größe und die Adresse des tatsächlichen Textes. Ein solches Muster würde es dem Code ermöglichen, einen beliebigen Teilstring (nicht nur den Schwanz) eines anderen Strings zu übergeben, ohne etwas kopieren zu müssen, und würde es Methoden ermöglichen , so viel wie getsund strcatsicher zu akzeptieren, wie es passt.
Supercat

16

Sie sollten es nicht verwenden, getsda es keine Möglichkeit gibt, einen Pufferüberlauf zu stoppen. Wenn der Benutzer mehr Daten eingibt, als in Ihren Puffer passen, werden Sie höchstwahrscheinlich beschädigt oder schlimmer.

Tatsächlich hat ISO den Schritt unternommen , gets den C-Standard zu entfernen (ab C11, obwohl er in C99 veraltet war), was angesichts der hohen Bewertung der Abwärtskompatibilität ein Hinweis darauf sein sollte, wie schlecht diese Funktion war.

Das Richtige ist, die fgetsFunktion mit dem stdinDateihandle zu verwenden, da Sie die vom Benutzer gelesenen Zeichen einschränken können.

Dies hat aber auch folgende Probleme:

  • Vom Benutzer eingegebene zusätzliche Zeichen werden beim nächsten Mal erfasst.
  • Es gibt keine schnelle Benachrichtigung, dass der Benutzer zu viele Daten eingegeben hat.

Zu diesem Zweck wird fast jeder C-Codierer irgendwann in seiner Karriere auch einen nützlicheren Wrapper herumschreiben fgets. Hier ist meins:

#include <stdio.h>
#include <string.h>

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

mit etwas Testcode:

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        printf ("No input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long\n");
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}

Es bietet den gleichen Schutz wie fgetsinsofern, als es Pufferüberläufe verhindert, aber es benachrichtigt den Anrufer auch darüber, was passiert ist, und löscht die überschüssigen Zeichen, damit sie Ihre nächste Eingabeoperation nicht beeinträchtigen.

Fühlen Sie sich frei, es zu verwenden, wie Sie möchten, ich veröffentliche es hiermit unter der Lizenz "Mach was du verdammt gut willst" :-)


Tatsächlich wurde der ursprüngliche C99-Standard gets()weder in Abschnitt 7.19.7.7, in dem er definiert ist, noch in Abschnitt 7.26.9 Zukünftige Bibliotheksanweisungen und dem Unterabschnitt für explizit abgelehnt <stdio.h>. Es gibt nicht einmal eine Fußnote darüber, dass es gefährlich ist. (Allerdings sehe ich in der Antwort von Yu Hao "Es ist in ISO / IEC 9899: 1999 / Cor.3: 2007 (E) veraltet)" .) Aber C11 hat es aus dem Standard entfernt - und nicht vorzeitig !
Jonathan Leffler

int getLine (char *prmpt, char *buff, size_t sz) { ... if (fgets (buff, sz, stdin) == NULL)verbirgt die size_tzur intUmwandlung von sz. sz > INT_MAX || sz < 2würde seltsame Werte von fangen sz.
chux

if (buff[strlen(buff)-1] != '\n') {ist ein Hacker-Exploit, da das erste eingegebene Zeichen des bösen Benutzers ein eingebettetes Nullzeichen sein könnte, das buff[strlen(buff)-1]UB rendert. while (((ch = getchar())...hat Probleme, wenn ein Benutzer ein Nullzeichen eingibt.
chux

12

fgets .

Aus dem Standard lesen:

char string[512];

fgets(string, sizeof(string), stdin); /* no buffer overflows here, you're safe! */

6

Sie können API-Funktionen nicht entfernen, ohne die API zu beschädigen. Wenn Sie dies tun würden, würden viele Anwendungen überhaupt nicht mehr kompiliert oder ausgeführt.

Dies ist der Grund, den eine Referenz gibt:

Das Lesen einer Zeile, die über das Array läuft, auf das s zeigt, führt zu undefiniertem Verhalten. Die Verwendung von fgets () wird empfohlen.


4

Ich habe kürzlich in einem USENET-Beitragcomp.lang.c gelesen , dass dies gets()aus dem Standard entfernt wird. WOOHOO

Sie werden froh sein zu wissen, dass das Komitee gerade (wie sich herausstellt, einstimmig) dafür gestimmt hat, get () ebenfalls aus dem Entwurf zu entfernen.


3
Es ist ausgezeichnet, dass es aus dem Standard entfernt wird. Die meisten Implementierungen werden es jedoch aufgrund der Abwärtskompatibilität für mindestens die nächsten 20 Jahre als "jetzt nicht standardmäßige Erweiterung" bereitstellen.
Jonathan Leffler

1
Ja, richtig, aber wenn Sie mit gcc -std=c2012 -pedantic ...get () kompilieren, werden Sie nicht durchkommen. (Ich habe gerade den -stdParameter
erfunden

4

In C11 (ISO / IEC 9899: 201x) gets()wurde entfernt. (Es ist in ISO / IEC 9899: 1999 / Cor.3: 2007 (E) veraltet.)

Darüber hinaus fgets()stellt C11 eine neue sichere Alternative vor gets_s():

C11 K.3.5.4.1 Die gets_sFunktion

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
char *gets_s(char *s, rsize_t n);

Im Abschnitt Empfohlene Praxisfgets() wird dies jedoch weiterhin bevorzugt.

Mit dieser fgetsFunktion können ordnungsgemäß geschriebene Programme Eingabezeilen sicher verarbeiten, die zu lang sind, um sie im Ergebnisarray zu speichern. Im Allgemeinen erfordert dies, dass Anrufer fgetsauf das Vorhandensein oder Fehlen eines neuen Zeilenzeichens im Ergebnisarray achten. Erwägen Sie die Verwendung fgets(zusammen mit der erforderlichen Verarbeitung basierend auf Zeichen in neuen Zeilen) anstelle von gets_s.


3

gets()ist gefährlich, da der Benutzer das Programm abstürzen kann, indem er zu viel in die Eingabeaufforderung eingibt. Das Ende des verfügbaren Speichers kann nicht erkannt werden. Wenn Sie also eine zu kleine Speichermenge für diesen Zweck zuweisen, kann dies zu einem Seg-Fehler und einem Absturz führen. Manchmal scheint es sehr unwahrscheinlich, dass ein Benutzer 1000 Buchstaben in eine Eingabeaufforderung eingibt, die für den Namen einer Person bestimmt ist. Als Programmierer müssen wir unsere Programme jedoch kugelsicher machen. (Es kann auch ein Sicherheitsrisiko darstellen, wenn ein Benutzer ein Systemprogramm durch Senden zu vieler Daten zum Absturz bringen kann.)

fgets() Mit dieser Option können Sie angeben, wie viele Zeichen aus dem Standardeingabepuffer entfernt werden sollen, damit die Variable nicht überschritten wird.


Beachten Sie, dass die wirkliche Gefahr nicht darin besteht, dass Sie Ihr Programm zum Absturz bringen können, sondern dass es beliebigen Code ausführen kann . (Im Allgemeinen undefiniertes Verhalten ausnutzen .)
Tanz87

2

Ich möchte alle C-Bibliotheksbetreuer, die noch getsin ihre Bibliotheken aufgenommen haben, ernsthaft einladen, "nur für den Fall, dass noch jemand davon abhängig ist": Bitte ersetzen Sie Ihre Implementierung durch das Äquivalent von

char *gets(char *str)
{
    strcpy(str, "Never use gets!");
    return str;
}

Dies wird dazu beitragen, dass niemand mehr davon abhängig ist. Danke dir.


2

Die C-Funktion ist gefährlich und ein sehr kostspieliger Fehler. Tony Hoare hebt es in seinem Vortrag "Null References: The Billion Dollar Mistake" besonders hervor:

http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare

Die ganze Stunde ist sehenswert, aber für seine Kommentare bekommt die Ansicht ab 30 Minuten mit der spezifischen Kritik rund 39 Minuten.

Hoffentlich macht dies Appetit auf das ganze Gespräch, was darauf aufmerksam macht, wie wir formellere Korrektheitsnachweise in Sprachen benötigen und wie Sprachdesigner für die Fehler in ihren Sprachen verantwortlich gemacht werden sollten, nicht für den Programmierer. Dies scheint der zweifelhafte Grund für Designer schlechter Sprachen gewesen zu sein, Programmierern die Schuld unter dem Deckmantel der "Programmiererfreiheit" zu geben.

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.