Die Käfer, die dein Schloss zerstört haben

Walter Bright ist der "wohlwollende, lebenslange Diktator" der Programmiersprache D und Gründer von Digital Mars . Er verfügt über jahrzehntelange Erfahrung in der Entwicklung von Compilern und Interpreten für mehrere Sprachen, darunter Zortech C ++, der erste native C ++ - Compiler. Er ist auch der Schöpfer von Empire , der Hauptinspiration für Sid Meiers Civilization.



Bessere C-Serie


Sind Sie müde von Fehlern, die leicht zu machen und schwer zu finden sind, die beim Testen oft nicht auftauchen und Ihr sorgfältig konstruiertes Schloss zerstören, nachdem der Code in Produktion gegangen ist? Immer wieder kosten sie viel Zeit und Geld. Ah, wenn Sie nur ein besserer Programmierer wären, würde das nicht passieren, oder?



Oder vielleicht bist du es nicht? Ich werde Ihnen zeigen, dass diese Fehler nicht Ihre Schuld sind: Sie sind die Schuld der Werkzeuge, und wenn Sie nur die Werkzeuge verbessern, ist Ihr Schloss sicher.



Und Sie müssen nicht einmal Kompromisse eingehen.



Außerhalb der Grenzen eines Arrays



Nehmen wir ein allgemeines Programm zur Berechnung der Summe der Array-Werte:



#include <stdio.h>

#define MAX 10

int sumArray(int* p) {
    int sum = 0;
    int i;
    for (i = 0; i <= MAX; ++i)
        sum += p[i];
    return sum;
}

int main() {
    static int values[MAX] = { 7,10,58,62,93,100,8,17,77,17 };
    printf("sum = %d\n", sumArray(values));
    return 0;
}


Das Programm sollte drucken:



sum = 449


Und genau das macht es - auf meinem Ubuntu Linux-Rechner: in gcc, clang und sogar mit einer Flagge -Wall. Ich bin sicher, Sie haben bereits erraten, was der Fehler ist:



for (i = 0; i <= MAX; ++i)
              ^^


. 11 10. :



for (i = 0; i < MAX; ++i)


, , ! , . . , « » . , .



, , :



  1. - , ;
  2. - <= .


, ! ? . , . , sumArray . :



  1. , sumArray, , .
  2. , .
  3. , MAX.


, . sumArray , , , , , .



— , ? - , ? ? , . .



, , , . . . ( , gcc, clang , , - , ).



, — D -betterC. D , . , :



struct DynamicArray {
    T* ptr;
    size_t length;
}


:



int[] a;


:



import core.stdc.stdio;

extern (C):   // use C ABI for declarations

enum MAX = 10;

int sumArray(int[] a) {
    int sum = 0;
    for (int i = 0; i <= MAX; ++i)
        sum += a[i];
    return sum;
}

int main() {
    __gshared int[MAX] values = [ 7,10,58,62,93,100,8,17,77,17 ];
    printf("sum = %d\n", sumArray(values));
    return 0;
}


:



dmd -betterC sum.d


:



./sum
Assertion failure: 'array overflow' on line 11 in file 'sum.d'


- . <= < :



./sum
sum = 449


? a , .



, .



MAX. a , :



for (int i = 0; i < a.length; ++i)


, D :



foreach (value; a)
    sum += value;


sumArray :



int sumArray(int[] a) {
    int sum = 0;
    foreach (value; a)
        sum += value;
    return sum;
}


sumArray . , . , .



— ! — . — a sumArray , p . , , .



— , MAX , , :



int sumArray(int *p, size_t length);


, . D , .



int sumArray(ref int[MAX] a) {
    int sum = 0;
    foreach (value; a)
        sum += value;
    return sum;
}


? a, ref, . MAX , . , sumArray, , .



— ! — . — D . , ? ? , !



, :



import core.stdc.stdio;

extern (C):   // use C ABI for declarations

enum MAX = 10;

int sumArray(int* p) {
    int sum = 0;
    for (int i = 0; i <= MAX; ++i)
        sum += p[i];
    return sum;
}

int main() {
    __gshared int[MAX] values = [ 7,10,58,62,93,100,8,17,77,17 ];
    printf("sum = %d\n", sumArray(&values[0]));
    return 0;
}


, . , :



sum = 39479


, 449, .



, ? @safe:



import core.stdc.stdio;

extern (C):   // use C ABI for declarations

enum MAX = 10;

@safe int sumArray(int* p) {
    int sum = 0;
    for (int i = 0; i <= MAX; ++i)
        sum += p[i];
    return sum;
}

int main() {
    __gshared int[MAX] values = [ 7,10,58,62,93,100,8,17,77,17 ];
    printf("sum = %d\n", sumArray(&values[0]));
    return 0;
}


:



sum.d(10): Error: safe function 'sum.sumArray' cannot index pointer 'p'


, - grep, , @safe, .



, , , , . , . . , ! ( ).




All Articles