ウォルターブライトのDプログラミング言語と創業者の「慈悲深い、生涯の独裁者」であるデジタル火星。彼は、最初のネイティブC ++コンパイラであるZortechC ++を含む、いくつかの言語用のコンパイラとインタプリタの開発に12年以上の経験があります。彼はまた、シド・マイヤーの文明の主なインスピレーションであるエンパイアの作成者でもあります。
Better Cは、既存のCプロジェクトを一貫した方法でDに移植する方法です。この記事では、重要なプロジェクトをCからDに変換するためのステップバイステップのプロセスを示し、発生する一般的な問題を示します。
DコンパイラのdmdのフロントエンドはすでにDに変換されていますが、非常に大きなプロジェクトであるため、完全に網羅することは困難です。完全に理解できるが、投機的な例ではない、より小さく、より控えめなプロジェクトが必要でした。
1980年代初頭にDatalightCコンパイラ用に作成した古いmakeプログラムが思い浮かびました。これは、1980年代初頭から絶えず使用されてきた古典的なmakeプログラムの実際の実装です。標準化される前からCで記述されており、あるシステムから別のシステムに移植され、コメントを含めて1961行のコードに収まります。それは今日でも定期的に使用されています。
これがドキュメントとソースコードです。make.exe実行可能ファイルのサイズは49,692バイトで、最終変更日は2012年8月19日です。
私たちの邪悪な計画:
- 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, , :
- !
- 安全なメモリアクセス(バッファオーバーフローチェックを含む)、
- メタプログラミング、
- RAII、
- Unicode、
- ネストされた関数、
- メソッド、
- オペレーターの過負荷、
- ドキュメントジェネレータ、
- 機能プログラミング、
- コンパイル時関数実行(CTFE)、
- とはるかに。
アクションに
英語をご存知の場合は、フォーラムDにアクセスして、BetterCプロジェクトの進捗状況をお知らせください。