Walter Bright adalah "diktator seumur hidup yang baik hati" dari bahasa pemrograman D dan pendiri Digital Mars . Dia memiliki lebih dari belasan tahun pengalaman dalam mengembangkan compiler dan interpreter untuk beberapa bahasa, termasuk Zortech C ++, compiler C ++ native pertama. Dia juga pencipta Kekaisaran , inspirasi utama untuk Peradaban Sid Meier.
C yang lebih baik adalah cara untuk memindahkan proyek C yang ada ke D secara konsisten. Artikel ini memandu Anda melalui proses langkah demi langkah untuk mengubah proyek non-sepele dari C ke D dan menunjukkan kepada Anda masalah umum yang muncul.
Meskipun frontend dari kompilator D dmd telah diubah menjadi D, ini adalah proyek yang sangat besar sehingga sulit untuk menutupinya sepenuhnya. Saya membutuhkan proyek yang lebih kecil dan lebih sederhana yang dapat dipahami sepenuhnya tanpa menjadi contoh spekulatif.
Sebuah program make lama yang saya tulis untuk kompiler Datalight C di awal 1980-an muncul di benak saya . Ini adalah implementasi nyata dari program make klasik, yang telah digunakan secara konstan sejak awal 1980-an. Itu ditulis dalam C bahkan sebelum standarisasi, porting dari satu sistem ke sistem lain, dan hanya cocok di 1961 baris kode, termasuk komentar. Itu masih digunakan secara teratur sampai sekarang.
Berikut dokumentasi dan kode sumbernya . Ukuran eksekusi make.exe adalah 49.692 byte dan terakhir diubah pada 19 Agustus 2012.
Rencana Jahat Kami:
- Minimalkan perbedaan antara versi C dan D. Dengan demikian, jika perilaku program berbeda, akan lebih mudah menemukan sumber perbedaannya.
- 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, , :
- !
- akses memori yang aman (termasuk pemeriksaan buffer overflow ),
- metaprogramming,
- RAII ,
- Unicode,
- fungsi bersarang ,
- metode ,
- kelebihan beban operator ,
- generator dokumentasi ,
- pemrograman fungsional ,
- eksekusi fungsi waktu kompilasi (CTFE) ,
- dan masih banyak lagi .
Beraksi
Jika Anda tahu bahasa Inggris, kunjungi Forum D dan beri tahu kami bagaimana kemajuan proyek Better C Anda!