والتر برايت هو "الدكتاتور الخير مدى الحياة" للغة البرمجة D ومؤسس Digital Mars . لديه عقود من الخبرة في تطوير المترجمين والمترجمين الفوريين لعدة لغات ، بما في ذلك Zortech C ++ ، أول مترجم أصلي لـ 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 الخاص بي: في دول مجلس التعاون الخليجي ، و clang ، وحتى مع العلم -Wall
. أنا متأكد من أنك خمنت بالفعل ما هو الخطأ:
for (i = 0; i <= MAX; ++i)
^^
for (i = 0; i < MAX; ++i)
, , :
- - , ;
- -
<=
.
, ! ? . , . , sumArray
. :
- ,
sumArray
, , . - , .
- ,
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
, .
, , , , . , . . , ! ( ).