沃尔特·布赖特(Walter Bright)是D编程语言的“仁慈终身独裁者”,也是Digital Mars的创始人。他在开发多种语言的编译器和解释器方面拥有数十年的经验,其中包括第一个本机C ++编译器Zortech C ++。他还是《帝国》的创建者,《帝国》是西德·迈耶《文明》的主要灵感来源。
更好的C是一种以一致的方式将现有C项目移植到D的方法。本文分步介绍了将不重要的项目从C转换为D的分步过程,并向您展示了出现的常见问题。
尽管D编译器dmd的前端已经转换为D,但它是一个庞大的项目,因此很难完全覆盖它。我需要一个可以完全理解的较小且较谦虚的项目,但这不是一个投机的例子。
我想到了我在1980年代初为Datalight C编译器编写的旧的make程序。这是经典make程序的真实实现,该程序自1980年代初以来一直在使用。它甚至在标准化之前就用C编写,从一个系统移植到另一个系统,并且仅包含1961行代码,包括注释。今天仍然经常使用。
这是文档和源代码。make.exe可执行文件的大小为49,692字节,最后修改于2012年8月19日。
我们的邪恶计划:
- 最小化C版本和D版本之间的差异。因此,如果程序的行为不同,则更容易找到差异的根源。
- 在迁移过程中,不会尝试修复或改进C代码,这是按照第1点进行的。
- 不会尝试重构代码。同样,请参见第1点。
- 尽可能重现所有错误的C程序的行为。
- 为了实现第4段,请做所有必要的事情。
只有完成后,我们才能开始修复,重构,调整等。
剧透!
从C到D的传输完成。可执行文件的大小为52,252字节(相比之下,原始文件为49,692字节)。我没有分析大小的增加,但是可能是由于NEWOBJ模板的实例(在C版本中,这是一个宏)以及2012年之后DMC运行时的变化。
一步步
#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, , :
采取行动
如果您会英语,请前往论坛D并告诉我们您的Better C项目的进展情况!