والتر برايت هو "الدكتاتور الخير مدى الحياة" للغة البرمجة D ومؤسس Digital Mars . لديه عقود من الخبرة في تطوير المترجمين والمترجمين الفوريين لعدة لغات ، بما في ذلك Zortech C ++ ، أول مترجم أصلي لـ C ++. وهو أيضًا منشئ الإمبراطورية ، الملهم الرئيسي لحضارة سيد ماير.
أفضل C هو وسيلة لنقل مشاريع C الحالية إلى D بطريقة متسقة. ترشدك هذه المقالة خلال العملية خطوة بخطوة لتحويل مشروع غير تافه من C إلى D وتوضح لك المشكلات الشائعة التي تنشأ.
على الرغم من أن الواجهة الأمامية لمترجم D dmd قد تم تحويلها بالفعل إلى D ، إلا أنه مشروع كبير يصعب تغطيته بالكامل. كنت بحاجة إلى مشروع أصغر وأكثر تواضعًا يمكن فهمه تمامًا ، لكنه لم يكن مثالًا تخمينيًا.
لقد خطر ببالي برنامج صنع قديم كتبته لمجمع Datalight C في أوائل الثمانينيات. يعد هذا تطبيقًا حقيقيًا لبرنامج Make الكلاسيكي الذي ظل قيد الاستخدام المستمر منذ أوائل الثمانينيات. تمت كتابتها بلغة C حتى قبل توحيدها ، وتم نقلها من نظام إلى آخر ، وتناسب فقط 1961 سطرًا من التعليمات البرمجية ، بما في ذلك التعليقات. لا يزال يستخدم بانتظام اليوم.
هنا هو وثائق و شفرة المصدر . حجم الملف التنفيذي make.exe هو 49،692 بايت وتم تعديله آخر مرة في 19 أغسطس 2012.
خطتنا الشريرة:
- تصغير الفروق بين الإصدارات C و D. وبالتالي ، إذا اختلف سلوك البرامج ، فسيكون من الأسهل العثور على مصدر الاختلاف.
- C. № 1.
- . , . № 1.
- C , .
- , № 4.
, , , ..
!
C D. — 52 252 ( — 49 692 ). , , - NEWOBJ ( C- ) DMC 2012 .
#include
D: , #include <stdio.h>
import core.stdc.stdio;
. , Digital Mars C, D ( ). , 29- 64-. (. import
).
#if _WIN32
version (Windows)
. (. ).
extern(C):
C. (. ).
debug1, debug2 debug3 debug prinf
. , #ifdef DEBUG
debug
. (. debug
).
/* Delete these old C macro definitions...
#ifdef DEBUG
-#define debug1(a) printf(a)
-#define debug2(a,b) printf(a,b)
-#define debug3(a,b,c) printf(a,b,c)
-#else
-#define debug1(a)
-#define debug2(a,b)
-#define debug3(a,b,c)
-#endif
*/
// And replace their usage with the debug statement
// debug2("Returning x%lx\n",datetime);
debug printf("Returning x%lx\n",datetime);
TRUE, FALSE NULL true
, false
null
.
ESC . (. ).
// #define ESC '!'
enum ESC = '!';
NEWOBJ .
// #define NEWOBJ(type) ((type *) mem_calloc(sizeof(type)))
type* NEWOBJ(type)() { return cast(type*) mem_calloc(type.sizeof); }
D (thread-local storage, TLS). make
— , __gshared
. (. __gshared
).
// int CMDLINELEN;
__gshared int CMDLINELEN
D , typedef
. alias
. (. alias
). , struct
.
/*
typedef struct FILENODE
{ char *name,genext[EXTMAX+1];
char dblcln;
char expanding;
time_t time;
filelist *dep;
struct RULE *frule;
struct FILENODE *next;
} filenode;
*/
struct FILENODE
{
char *name;
char[EXTMAX1] genext;
char dblcln;
char expanding;
time_t time;
filelist *dep;
RULE *frule;
FILENODE *next;
}
alias filenode = FILENODE;
D macro
— , MACRO
.
// char *name,*text;
// In D, the * is part of the type and
// applies to each symbol in the declaration.
char* name, text;
static
D . C D, , . __gshared
, . (. static
).
/*
static ignore_errors = FALSE;
static execute = TRUE;
static gag = FALSE;
static touchem = FALSE;
static debug = FALSE;
static list_lines = FALSE;
static usebuiltin = TRUE;
static print = FALSE;
...
*/
__gshared
{
bool ignore_errors = false;
bool execute = true;
bool gag = false;
bool touchem = false;
bool xdebug = false;
bool list_lines = false;
bool usebuiltin = true;
bool print = false;
...
}
, , , D .
// int cdecl main(int argc,char *argv[])
int main(int argc,char** argv)
mem_init()
, .
void cmderr(const char* format, const char* arg) {...}
// cmderr("can't expand response file\n");
cmderr("can't expand response file\n", null);
- (->
) C (.
), D .
/*
#if TERMCODE
...
#endif
*/
version (TERMCODE)
{
...
}
// doswitch(p)
// char *p;
void doswitch(char* p)
D debug
. xdebug
.
C \n\
. D .
/+ +/
. (. , ).
// utime(name,timep);
utime(name,timep.ptr);
const
C D, D . (. const
immutable
).
// linelist **readmakefile(char *makefile,linelist **rl)
linelist **readmakefile(const char *makefile,linelist **rl)
void*
char*
D .
// buf = mem_realloc(buf,bufmax);
buf = cast(char*)mem_realloc(buf,bufmax);
inout
, «» . const
, , . (. inout
-).
// char *skipspace(p) {...}
inout(char) *skipspace(inout(char)* p) {...}
arraysize
.length
. (. ).
// useCOMMAND |= inarray(p,builtin,arraysize(builtin));
useCOMMAND |= inarray(p,builtin.ptr,builtin.length)
(immutable
), , . (. ).
// static char envname[] = "@_CMDLINE";
char[10] envname = "@_CMDLINE";
.sizeof
sizeof()
C. (. .sizeof
).
// q = (char *) mem_calloc(sizeof(envname) + len);
q = cast(char *) mem_calloc(envname.sizeof + len)
Windows .
char *
void*
.
! , . , , — , .
make , make-:
\dmd2.079\windows\bin\dmd make.d dman.d -O -release -betterC -I. -I\dmd2.079\src\druntime\import\ shell32.lib
C D, . .
, , :
-
#include
import
; - D- ;
-
->
; - :
- ,
- ,
- ,
- ,
- ;
- ;
- ;
- ;
- ;
- ;
- C D.
:
- ,
- ,
- ,
- ,
- .
, Better C, , :
- !
- الوصول الآمن للذاكرة (بما في ذلك فحص تجاوز سعة المخزن المؤقت ) ،
- metaprogramming ،
- RAII ،
- يونيكود
- وظائف متداخلة ،
- طرق ،
- المشغل الزائد ،
- مولد الوثائق ،
- البرمجة الوظيفية ،
- تنفيذ وظيفة الترجمة (CTFE) ،
- وأكثر من ذلك بكثير .
للعمل
إذا كنت تعرف اللغة الإنجليزية ، فتوجه إلى المنتدى D وأخبرنا عن مدى تقدم مشروع Better C!