{"id":1579,"date":"2018-06-11T13:51:16","date_gmt":"2018-06-11T13:51:16","guid":{"rendered":"http:\/\/dlang.org\/blog\/?p=1579"},"modified":"2021-10-08T11:03:55","modified_gmt":"2021-10-08T11:03:55","slug":"dasbetterc-converting-make-c-to-d","status":"publish","type":"post","link":"https:\/\/dlang.org\/blog\/2018\/06\/11\/dasbetterc-converting-make-c-to-d\/","title":{"rendered":"DasBetterC: Converting make.c to D"},"content":{"rendered":"<p><em><a href=\"http:\/\/walterbright.com\/\">Walter Bright<\/a> is the BDFL of the D Programming Language and founder of <a href=\"http:\/\/digitalmars.com\/\">Digital Mars<\/a>. He has decades of experience implementing compilers and interpreters for multiple languages, including Zortech C++, the first native C++ compiler. He also created <a href=\"http:\/\/www.classicempire.com\/\">Empire, the Wargame of the Century<\/a>. This post is <a href=\"https:\/\/dlang.org\/blog\/the-d-and-c-series\/#betterC\">the third in a series<\/a>\u00a0about\u00a0<a href=\"https:\/\/dlang.org\/blog\/2017\/08\/23\/d-as-a-better-c\/\">D\u2019s BetterC mode<\/a><\/em><\/p>\n<hr \/>\n<p><img loading=\"lazy\" class=\"alignleft size-full wp-image-181\" src=\"http:\/\/dlang.org\/blog\/wp-content\/uploads\/2016\/08\/d6.png\" alt=\"\" width=\"200\" height=\"200\" \/>D as BetterC (a.k.a. DasBetterC) is a way to upgrade existing C projects to D in an incremental manner. This article shows a step-by-step process of converting a non-trivial C project to D and deals with common issues that crop up.<\/p>\n<p>While <a href=\"https:\/\/github.com\/dlang\/dmd\">the dmd D compiler front end<\/a> has already been converted to D, it\u2019s such a large project that it can be hard to see just what was involved. I needed to find a smaller, more modest project that can be easily understood in its entirety, yet is not a contrived example.<\/p>\n<p>The old make program I wrote for the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Datalight\">Datalight C compiler<\/a> in the early 1980\u2019s came to mind. It\u2019s a real implementation of the classic make program that\u2019s been in constant use since the early 80\u2019s. It\u2019s written in pre-Standard C, has been ported from system to system, and is a remarkably compact 1961 lines of code, including comments. It is still in regular use today.<\/p>\n<p>Here\u2019s the <a href=\"https:\/\/digitalmars.com\/ctg\/make.html\">make manual<\/a>, and the <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/473bf5bef99a1748d5154b343b986534271cd841#diff-14c44b49b9f46b1aeab33a6684214e55\">source code<\/a>. The executable size for make.exe is 49,692 bytes and the last modification date was Aug 19, 2012.<\/p>\n<p>The Evil Plan is:<\/p>\n<ol>\n<li>Minimize diffs between the C and D versions. This is so that if the programs behave differently, it is far easier to figure out the source of the difference.<\/li>\n<li>No attempt will be made to fix or improve the C code during translation. This is also in the service of (1).<\/li>\n<li>No attempt will be made to refactor the code. Again, see (1).<\/li>\n<li>Duplicate the behavior of the C program as exactly and as much as possible,<br \/>\nbugs and all.<\/li>\n<li>Do whatever is necessary as needed in the service of (4).<\/li>\n<\/ol>\n<p>Once that is completed, only then is it time to fix, refactor, clean up, etc.<\/p>\n<h2 id=\"spoileralert\">Spoiler Alert!<\/h2>\n<p>The <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/blob\/1dbd3e3381c8f7f7ab2e35214dcd63455ae38c29\/dm\/src\/make\/dmake.d\">completed conversion<\/a>. The resulting executable is 52,252 bytes (quite comparable to the original 49,692). I haven\u2019t analyzed the increment in size, but it is likely due to instantiations of the <code>NEWOBJ<\/code> template (a macro in the C version), and changes in the DMC runtime library since 2012.<\/p>\n<h2 id=\"stepbystep\">Step By Step<\/h2>\n<p>Here are the differences between the <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34\">C and D versions<\/a>. It\u2019s 664 out of 1961 lines, about a third, which looks like a lot, but I hope to convince you that nearly all of it is trivial.<\/p>\n<p>The <code>#include files are replaced<\/code> by corresponding D imports, such as <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R11\">replacing <code>#include &lt;stdio.h&gt;<\/code> with <code>import core.stdc.stdio;<\/code><\/a>. Unfortunately, some of the <code>#include<\/code> files are specific to Digital Mars C, and D versions do not exist (I need to fix that). To not let that stop the project, I simply included the <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R29\">relevant declarations in lines 29 to 64<\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/module.html#import-declaration\">for the <code>import<\/code> declaration<\/a>.)<\/p>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L23\"><code>#if _WIN32<\/code> is replaced<\/a> with <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R20\"><code>version (Windows)<\/code><\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/version.html#version\">for the version condition<\/a> and <a href=\"https:\/\/dlang.org\/spec\/version.html#predefined-versions\">predefined versions<\/a>.)<\/p>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R27\"><code>extern (C):<\/code><\/a> marks the remainder of the declarations in the file as compatible with C. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/attribute.html#linkage\">for the linkage attribute<\/a>.)<\/p>\n<p>A global search\/replace changes uses of the <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L27\">debug1, debug2 and debug3<\/a> macros to <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R499\">debug printf<\/a>. In general, <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff\u201314c44b49b9f46b1aeab33a6684214e55L290\"><code>#ifdef DEBUG<\/code> preprocessor directives<\/a> are replaced with <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R276\"><code>debug<\/code> conditional compilation<\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/version.html#DebugStatement\">for the <code>debug<\/code> statement<\/a>.)<\/p>\n<pre class=\"prettyprint lang-d\">\/* Delete these old C macro definitions...\r\n#ifdef DEBUG\r\n-#define debug1(a)       printf(a)\r\n-#define debug2(a,b)     printf(a,b)\r\n-#define debug3(a,b,c)   printf(a,b,c)\r\n-#else\r\n-#define debug1(a)\r\n-#define debug2(a,b)\r\n-#define debug3(a,b,c)\r\n-#endif\r\n*\/\r\n\r\n\/\/ And replace their usage with the debug statement\r\n\/\/ debug2(\"Returning x%lx\\n\",datetime);\r\ndebug printf(\"Returning x%lx\\n\",datetime);<\/pre>\n<p>The <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L37\"><code>TRUE<\/code>, <code>FALSE<\/code><\/a> and <code>NULL<\/code> macros are search\/replaced with <code>true<\/code>, <code>false<\/code>, and <code>null<\/code>.<\/p>\n<p>The <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L40\"><code>ESC macro is replaced<\/code><\/a> by a <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R66\">manifest constant<\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/enum.html#manifest_constants\">for manifest constants<\/a>.)<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ #define ESC     '!'\r\nenum ESC =      '!';<\/pre>\n<p>The <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L42\"><code>NEWOBJ macro is replaced<\/code><\/a> with a <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R68\">template function<\/a>.<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ #define NEWOBJ(type)    ((type *) mem_calloc(sizeof(type)))\r\ntype* NEWOBJ(type)() { return cast(type*) mem_calloc(type.sizeof); }<\/pre>\n<p>The <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L56\"><code>filenamecmp<\/code> macro is replaced<\/a> with <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R74\">a function<\/a>.<\/p>\n<p>Support for <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L45\">obsolete platforms is removed<\/a>.<\/p>\n<p>Global variables in D are placed by default into thread-local storage (TLS). But since <code>make<\/code> is a single-threaded program, they can be inserted into global storage with the <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R82\"><code>__gshared<\/code> storage class<\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/attribute.html#gshared\">for the <code>__gshared<\/code> attribute<\/a>.)<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ int CMDLINELEN;\r\n__gshared int CMDLINELEN<\/pre>\n<p>D doesn\u2019t have a separate struct tag name space, so the typedefs are not necessary. An<br \/>\n<a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R113\"><code>alias<\/code><\/a> can be used instead.\u00a0(See the documentation <a href=\"https:\/\/dlang.org\/spec\/declaration.html#alias\">for <code>alias<\/code> declarations<\/a>.) Also,\u00a0<a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R131\"><code>struct<\/code><\/a> is omitted from variable declarations.<\/p>\n<pre class=\"prettyprint lang-d\">\/*\r\ntypedef struct FILENODE\r\n        {       char            *name,genext[EXTMAX+1];\r\n                char            dblcln;\r\n                char            expanding;\r\n                time_t          time;\r\n                filelist        *dep;\r\n                struct RULE     *frule;\r\n                struct FILENODE *next;\r\n        } filenode;\r\n*\/\r\nstruct FILENODE\r\n{\r\n        char            *name;\r\n        char[EXTMAX1]  genext;\r\n        char            dblcln;\r\n        char            expanding;\r\n        time_t          time;\r\n        filelist        *dep;\r\n        RULE            *frule;\r\n        FILENODE        *next;\r\n}\r\n\r\nalias filenode = FILENODE;<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L86\"><code>macro<\/code> is a keyword in D<\/a>, so we\u2019ll just use <code>MACRO<\/code> instead.<\/p>\n<p>Grouping together <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L83\">multiple pointer declarations<\/a> is not allowed in D, <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R98\">use this instead<\/a>:<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ char *name,*text;\r\n\/\/ In D, the * is part of the type and \r\n\/\/ applies to each symbol in the declaration.\r\nchar* name, text;<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L111\">C array declarations<\/a> are transformed to <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R131\">D array declarations<\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/declaration.html#declaration_syntax\">for D\u2019s declaration syntax<\/a>.)<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ char            *name,genext[EXTMAX+1];\r\nchar            *name;\r\nchar[EXTMAX+1]  genext;<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L159\"><code>static<\/code><\/a> has no meaning at module scope in D. <code>static<\/code> globals in C are equivalent to <code>private<\/code> module-scope variables in D, but that doesn\u2019t really matter when the module is never imported anywhere. They still need to be <code>__gshared<\/code> and that can be <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R191\">applied to an entire block of declarations<\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/attribute.html#static\">for the <code>static<\/code> attribute<\/a>)<\/p>\n<pre class=\"prettyprint lang-d\">\/*\r\nstatic ignore_errors = FALSE;\r\nstatic execute = TRUE;\r\nstatic gag = FALSE;\r\nstatic touchem = FALSE;\r\nstatic debug = FALSE;\r\nstatic list_lines = FALSE;\r\nstatic usebuiltin = TRUE;\r\nstatic print = FALSE;\r\n...\r\n*\/\r\n\r\n__gshared\r\n{\r\n    bool ignore_errors = false;\r\n    bool execute = true;\r\n    bool gag = false;\r\n    bool touchem = false;\r\n    bool xdebug = false;\r\n    bool list_lines = false;\r\n    bool usebuiltin = true;\r\n    bool print = false;\r\n    ...\r\n}<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L189\">Forward reference declarations<\/a> for functions are not necessary in D. Functions defined in a module can be called at any point in the same module, before or after their definition.<\/p>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L240\">Wildcard expansion<\/a> doesn\u2019t have much meaning to a <code>make<\/code> program.<\/p>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L242\">Function parameters declared with array syntax<\/a> are pointers in reality, and are declared as pointers in D.<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ int cdecl main(int argc,char *argv[])\r\nint main(int argc,char** argv)<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L248\"><code>mem_init()<\/code> expands to nothing<\/a> and we previously removed the macro.<\/p>\n<p>C code can play fast and loose with <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L275\">arguments to functions<\/a>, D demands that function prototypes be respected.<\/p>\n<pre class=\"prettyprint lang-d\">void cmderr(const char* format, const char* arg) {...}\r\n\r\n\/\/ cmderr(\"can't expand response file\\n\");\r\ncmderr(\"can't expand response file\\n\", null);<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L297\">Global search\/replace\u00a0C&#8217;s arrow operator<\/a> (<code>-&gt;<\/code>) with the dot operator (<code>.<\/code>), as member access in D is uniform.<\/p>\n<p>Replace <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L303\">conditional compilation directives<\/a> with D\u2019s <code>version<\/code>.<\/p>\n<pre class=\"prettyprint lang-d\">\/*\r\n #if TERMCODE\r\n    ...\r\n #endif\r\n*\/\r\n    version (TERMCODE)\r\n    {\r\n        ...\r\n    }<\/pre>\n<p>The <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R312\">lack of function prototypes<\/a> shows the age of this code. D requires proper prototypes.<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ doswitch(p)\r\n\/\/ char *p;\r\nvoid doswitch(char* p)<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L335\"><code>debug<\/code> is a D keyword<\/a>. Rename it to <code>xdebug<\/code>.<\/p>\n<p>The <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L396\"><code>\\n\\<\/code> line endings<\/a> for C multiline string literals are not necessary in D.<\/p>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R463\">Comment out unused code<\/a> using D\u2019s <code>\/+ +\/<\/code>\u00a0nesting block comments. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/lex.html#comment\">for line, block and nesting block comments<\/a>.)<\/p>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R503\"><code>static if<\/code> can replace<\/a>\u00a0many uses of <code>#if<\/code>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/version.html#staticif\">for the <code>static if<\/code> condition<\/a>.)<\/p>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L585\">Decay of arrays to pointers<\/a> is not automatic in D, use <code>.ptr<\/code>.<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ utime(name,timep);\r\nutime(name,timep.ptr);<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L658\">Use <code>const<\/code> for C-style strings<\/a> derived from string literals in D, because D won\u2019t allow taking mutable pointers to string literals. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/const3.html#const_and_immutable\">for <code>const<\/code> and <code>immutable<\/code><\/a>.)<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ linelist **readmakefile(char *makefile,linelist **rl)\r\nlinelist **readmakefile(const char *makefile,linelist **rl)<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R920\"><code>void*<\/code> cannot be implicitly cast to <code>char*<\/code><\/a>. Make it explicit.<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ buf = mem_realloc(buf,bufmax);\r\nbuf = cast(char*)mem_realloc(buf,bufmax);<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1099\">Replace <code>unsigned<\/code> with <code>uint<\/code><\/a>.<\/p>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R1160\"><code>inout<\/code> can be used to transfer<\/a> the \u201cconst-ness\u201d of a function from its argument to its return value. If the parameter is <code>const<\/code>, so will be the return value. If the parameter is not <code>const<\/code>, neither will be the return value. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/function.html#inout-functions\">for <code>inout<\/code> functions<\/a>.)<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ char *skipspace(p) {...}\r\ninout(char) *skipspace(inout(char)* p) {...}<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1628\"><code>arraysize<\/code> can be replaced<\/a> with the <code>.length<\/code> property of arrays. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/arrays.html#array-properties\">for array properties<\/a>.)<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ useCOMMAND  |= inarray(p,builtin,arraysize(builtin));\r\nuseCOMMAND  |= inarray(p,builtin.ptr,builtin.length)<\/pre>\n<p>String literals are immutable, so it is necessary to <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1683\">replace mutable ones with a stack allocated array<\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/lex.html#string_literals\">for string literals<\/a>.)<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ static char envname[] = \"@_CMDLINE\";\r\nchar[10] envname = \"@_CMDLINE\";<\/pre>\n<p><a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1688\"><code>.sizeof<\/code> replaces C\u2019s <code>sizeof()<\/code><\/a>. (See the documentation <a href=\"https:\/\/dlang.org\/spec\/property.html#sizeof\">for the <code>.sizeof<\/code> property<\/a>).<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ q = (char *) mem_calloc(sizeof(envname) + len);\r\nq = cast(char *) mem_calloc(envname.sizeof + len);<\/pre>\n<p>Don\u2019t care about <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R1692\">old versions of Windows<\/a>.<\/p>\n<p>Replace ancient C usage of <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1773\"><code>char *<\/code> with <code>void*<\/code>.<\/a><\/p>\n<p>And that wraps up the changes! See, not so bad. I didn\u2019t set a timer, but I doubt this took more than an hour, including debugging a couple errors I made in the process.<\/p>\n<p>This leaves the file <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/473bf5bef99a1748d5154b343b986534271cd841#diff-69c1b24ec5df3f3b5a5bb99bc60345f7\">man.c<\/a>, which is used to open the browser on the <a href=\"https:\/\/digitalmars.com\/ctg\/make.html\">make manual page<\/a> when the <code>-man<\/code> switch is given. Fortunately, this was already ported to D, so we can just copy <a href=\"https:\/\/github.com\/DigitalMars\/Compiler\/commit\/7765879be1be6fcb3eb959d1598d8ff227c2b0af#diff-2bac52ea58e12548536bb246cced3af4\">that code<\/a>.<\/p>\n<p>Building <code>make<\/code> is so easy it doesn\u2019t even need a makefile:<\/p>\n<pre class=\"prettyprint lang-d\">\\dmd2.079\\windows\\bin\\dmd make.d dman.d -O -release -betterC -I. -I\\dmd2.079\\src\\druntime\\import\\ shell32.lib<\/pre>\n<h2 id=\"summary\">Summary<\/h2>\n<p>We\u2019ve stuck to the Evil Plan of translating a non-trivial old school C program to D, and thereby were able to do it quickly and get it working correctly. An equivalent executable was generated.<\/p>\n<p>The issues encountered are typical and easily dealt with:<\/p>\n<ul>\n<li>Replacement of <code>#include<\/code> with <code>import<\/code><\/li>\n<li>Lack of D versions of <code>#include<\/code> files<\/li>\n<li>Global search\/replace of things like <code>-&gt;<\/code><\/li>\n<li>Replacement of preprocessor macros with:\n<ul>\n<li>manifest constants<\/li>\n<li>simple templates<\/li>\n<li>functions<\/li>\n<li>version declarations<\/li>\n<li>debug declarations<\/li>\n<\/ul>\n<\/li>\n<li>Handling identifiers that are D keywords<\/li>\n<li>Replacement of C style declarations of pointers and arrays<\/li>\n<li>Unnecessary forward references<\/li>\n<li>More stringent typing enforcement<\/li>\n<li>Array handling<\/li>\n<li>Replacing C basic types with D types<\/li>\n<\/ul>\n<p>None of the following was necessary:<\/p>\n<ul>\n<li>Reorganizing the code<\/li>\n<li>Changing data or control structures<\/li>\n<li>Changing the flow of the program<\/li>\n<li>Changing how the program works<\/li>\n<li>Changing memory management<\/li>\n<\/ul>\n<h2 id=\"future\">Future<\/h2>\n<p>Now that it is in DasBetterC, there are lots of modern programming features available to improve the code:<\/p>\n<ul>\n<li><a href=\"https:\/\/dlang.org\/spec\/module.html\">modules!<\/a><\/li>\n<li>memory safety (including <a href=\"https:\/\/dlang.org\/spec\/arrays.html#bounds\">buffer overflow checking<\/a>)<\/li>\n<li>metaprogramming<\/li>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Resource_acquisition_is_initialization\">RAII<\/a><\/li>\n<li>Unicode<\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/function.html#nested\">nested functions<\/a><\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/class.html#member-functions\">member functions<\/a><\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/operatoroverloading.html\">operator overloading<\/a><\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/ddoc.html\">documentation generation<\/a><\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/function.html#pure-functions\">functional programming support<\/a><\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/function.html#interpretation\">Compile Time Function Execution<\/a><\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/spec.html\">etc.<\/a><\/li>\n<\/ul>\n<h2 id=\"action\">Action<\/h2>\n<p>Let us know over at the <a href=\"https:\/\/forum.dlang.org\/group\/general\">D Forum<\/a> how your DasBetterC project is coming along!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>D as BetterC (a.k.a. DasBetterC) is a way to upgrade existing C projects to D in an incremental manner. This article shows a step-by-step process of converting a non-trivial C project to D and deals with common issues that crop up.<\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[31,26,8],"tags":[],"_links":{"self":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1579"}],"collection":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/comments?post=1579"}],"version-history":[{"count":12,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1579\/revisions"}],"predecessor-version":[{"id":1601,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1579\/revisions\/1601"}],"wp:attachment":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/media?parent=1579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/categories?post=1579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/tags?post=1579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}