あなたの城を破壊したバグ

ウォルターブライトのDプログラミング言語と創業者の「慈悲深い、生涯の独裁者」であるデジタル火星彼は、最初のネイティブC ++コンパイラであるZortechC ++を含む、いくつかの言語用のコンパイラとインタプリタの開発に12年以上の経験があります。彼はまた、シド・マイヤーの文明の主なインスピレーションであるエンパイアの作成者でもあります。



より良いCシリーズ


作成が簡単で見つけにくいバグにうんざりしていませんか?テスト中に表面化せず、コードの作成後に慎重に構築された城を破壊することがよくありますか?何度も何度も彼らはあなたに多くの時間とお金を要します。ああ、もしあなたがより優れたプログラマーだったら、それは起こらないでしょう?



それともあなたじゃないの?これらの間違いはあなたのせいではないことをお見せします。それらはツールのせいであり、ツールを改善するだけであれば、ロックは安全です。



そして、妥協する必要さえありません。



配列の範囲外



配列値の合計を計算するための一般的なプログラムを見てみましょう。



#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;
}


プログラムは次のように出力する必要があります。



sum = 449


そして、それはまさにそれが行うことです-私のUbuntu Linuxマシンでは、gcc、clang、さらにはフラグが付いています-Wall私はあなたがすでにエラーが何であるかを推測したと確信しています:



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