#[1]The D Blog » Feed [2]The D Blog » Comments Feed [3]The D Blog » DasBetterC: Converting make.c to D Comments Feed [4]Driving Continuous Improvement in D [5]How an Engineering Company Chose to Migrate to D [6]alternate [7]alternate [8]Menu * [9]Learn * [10]Documentation + [11]Language Reference + [12]Library Reference + [13]Command-line Reference + [14]Feature Overview + [15]Articles * * [16]Downloads * [17]Packages * [18]Community + [19]Blog + [20]Orgs using D + [21]Twitter + [22]Forums + [23]IRC + [24]Wiki + [25]GitHub + [26]Issues * [27]Resources + [28]Books + [29]Tutorials + [30]Tools + [31]Editors + [32]IDEs + [33]Visual D + [34]Acknowledgements + [35]D Style + [36]Glossary + [37]Sitemap [38]Skip to content [39]The D Blog The official blog for the D Programming Language. (BUTTON) Menu and widgets * [40]D Home * [41]D Forums * [42]Donate * [43]Shop D Language Foundation Donate Now DLang Swag Emporium [44]The Royal D Image [45]Shop now at the DLang Swag Emporium to support the D Language Foundation! Categories Categories[Select Category___] Subscriptions & Feedback * [46]Entries RSS * [47]Comments RSS * [48]Discussion * [49]Issues Pages * [50]D and C * [51]D in Production * [52]Symmetry Autumn of Code 2019 * [53]The GC Series Recent Posts * [54]Interfacing D with C: Arrays and Functions (Arrays Part 2) * [55]DustMite: The General-Purpose Data Reduction Tool * [56]D 2.091.0 Released * [57]Tracing D Applications * [58]News Update: Swag, Platforms, Documentation Help and More Archives Archives [Select Month__] DasBetterC: Converting make.c to D Posted on [59]June 11, 2018June 13, 2018Author [60]Walter Bright [61]Walter Bright is the BDFL of the D Programming Language and founder of [62]Digital Mars. He has decades of experience implementing compilers and interpreters for multiple languages, including Zortech C++, the first native C++ compiler. He also created [63]Empire, the Wargame of the Century. This post is [64]the third in a series about [65]D’s BetterC mode __________________________________________________________________ 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. While [66]the dmd D compiler front end has already been converted to D, it’s 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. The old make program I wrote for the [67]Datalight C compiler in the early 1980’s came to mind. It’s a real implementation of the classic make program that’s been in constant use since the early 80’s. It’s 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. Here’s the [68]make manual, and the [69]source code. The executable size for make.exe is 49,692 bytes and the last modification date was Aug 19, 2012. The Evil Plan is: 1. 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. 2. No attempt will be made to fix or improve the C code during translation. This is also in the service of (1). 3. No attempt will be made to refactor the code. Again, see (1). 4. Duplicate the behavior of the C program as exactly and as much as possible, bugs and all. 5. Do whatever is necessary as needed in the service of (4). Once that is completed, only then is it time to fix, refactor, clean up, etc. Spoiler Alert! The [70]completed conversion. The resulting executable is 52,252 bytes (quite comparable to the original 49,692). I haven’t analyzed the increment in size, but it is likely due to instantiations of the NEWOBJ template (a macro in the C version), and changes in the DMC runtime library since 2012. Step By Step Here are the differences between the [71]C and D versions. It’s 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. The #include files are replaced by corresponding D imports, such as [72]replacing #include with import core.stdc.stdio;. Unfortunately, some of the #include 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 [73]relevant declarations in lines 29 to 64. (See the documentation [74]for the import declaration.) [75]#if _WIN32 is replaced with [76]version (Windows). (See the documentation [77]for the version condition and [78]predefined versions.) [79]extern (C): marks the remainder of the declarations in the file as compatible with C. (See the documentation [80]for the linkage attribute.) A global search/replace changes uses of the [81]debug1, debug2 and debug3 macros to [82]debug printf. In general, [83]#ifdef DEBUG preprocessor directives are replaced with [84]debug conditional compilation. (See the documentation [85]for the debug statement.) /* 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); The [86]TRUE, FALSE and NULL macros are search/replaced with true, false, and null. The [87]ESC macro is replaced by a [88]manifest constant. (See the documentation [89]for manifest constants.) // #define ESC '!' enum ESC = '!'; The [90]NEWOBJ macro is replaced with a [91]template function. // #define NEWOBJ(type) ((type *) mem_calloc(sizeof(type))) type* NEWOBJ(type)() { return cast(type*) mem_calloc(type.sizeof); } The [92]filenamecmp macro is replaced with [93]a function. Support for [94]obsolete platforms is removed. Global variables in D are placed by default into thread-local storage (TLS). But since make is a single-threaded program, they can be inserted into global storage with the [95]__gshared storage class. (See the documentation [96]for the __gshared attribute.) // int CMDLINELEN; __gshared int CMDLINELEN D doesn’t have a separate struct tag name space, so the typedefs are not necessary. An [97]alias can be used instead. (See the documentation [98]for alias declarations.) Also, [99]struct is omitted from variable declarations. /* 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; [100]macro is a keyword in D, so we’ll just use MACRO instead. Grouping together [101]multiple pointer declarations is not allowed in D, [102]use this instead: // char *name,*text; // In D, the * is part of the type and // applies to each symbol in the declaration. char* name, text; [103]C array declarations are transformed to [104]D array declarations. (See the documentation [105]for D’s declaration syntax.) // char *name,genext[EXTMAX+1]; char *name; char[EXTMAX+1] genext; [106]static has no meaning at module scope in D. static globals in C are equivalent to private module-scope variables in D, but that doesn’t really matter when the module is never imported anywhere. They still need to be __gshared and that can be [107]applied to an entire block of declarations. (See the documentation [108]for the static attribute) /* 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; ... } [109]Forward reference declarations 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. [110]Wildcard expansion doesn’t have much meaning to a make program. [111]Function parameters declared with array syntax are pointers in reality, and are declared as pointers in D. // int cdecl main(int argc,char *argv[]) int main(int argc,char** argv) [112]mem_init() expands to nothing and we previously removed the macro. C code can play fast and loose with [113]arguments to functions, D demands that function prototypes be respected. void cmderr(const char* format, const char* arg) {...} // cmderr("can't expand response file\n"); cmderr("can't expand response file\n", null); [114]Global search/replace C’s arrow operator (->) with the dot operator (.), as member access in D is uniform. Replace [115]conditional compilation directives with D’s version. /* #if TERMCODE ... #endif */ version (TERMCODE) { ... } The [116]lack of function prototypes shows the age of this code. D requires proper prototypes. // doswitch(p) // char *p; void doswitch(char* p) [117]debug is a D keyword. Rename it to xdebug. The [118]\n\ line endings for C multiline string literals are not necessary in D. [119]Comment out unused code using D’s /+ +/ nesting block comments. (See the documentation [120]for line, block and nesting block comments.) [121]static if can replace many uses of #if. (See the documentation [122]for the static if condition.) [123]Decay of arrays to pointers is not automatic in D, use .ptr. // utime(name,timep); utime(name,timep.ptr); [124]Use const for C-style strings derived from string literals in D, because D won’t allow taking mutable pointers to string literals. (See the documentation [125]for const and immutable.) // linelist **readmakefile(char *makefile,linelist **rl) linelist **readmakefile(const char *makefile,linelist **rl) [126]void* cannot be implicitly cast to char*. Make it explicit. // buf = mem_realloc(buf,bufmax); buf = cast(char*)mem_realloc(buf,bufmax); [127]Replace unsigned with uint. [128]inout can be used to transfer the “const-ness” of a function from its argument to its return value. If the parameter is const, so will be the return value. If the parameter is not const, neither will be the return value. (See the documentation [129]for inout functions.) // char *skipspace(p) {...} inout(char) *skipspace(inout(char)* p) {...} [130]arraysize can be replaced with the .length property of arrays. (See the documentation [131]for array properties.) // useCOMMAND |= inarray(p,builtin,arraysize(builtin)); useCOMMAND |= inarray(p,builtin.ptr,builtin.length) String literals are immutable, so it is necessary to [132]replace mutable ones with a stack allocated array. (See the documentation [133]for string literals.) // static char envname[] = "@_CMDLINE"; char[10] envname = "@_CMDLINE"; [134].sizeof replaces C’s sizeof(). (See the documentation [135]for the .sizeof property). // q = (char *) mem_calloc(sizeof(envname) + len); q = cast(char *) mem_calloc(envname.sizeof + len); Don’t care about [136]old versions of Windows. Replace ancient C usage of [137]char * with void*. And that wraps up the changes! See, not so bad. I didn’t set a timer, but I doubt this took more than an hour, including debugging a couple errors I made in the process. This leaves the file [138]man.c, which is used to open the browser on the [139]make manual page when the -man switch is given. Fortunately, this was already ported to D, so we can just copy [140]that code. Building make is so easy it doesn’t even need a makefile: \dmd2.079\windows\bin\dmd make.d dman.d -O -release -betterC -I. -I\dmd2.079\src \druntime\import\ shell32.lib Summary We’ve 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. The issues encountered are typical and easily dealt with: * Replacement of #include with import * Lack of D versions of #include files * Global search/replace of things like -> * Replacement of preprocessor macros with: + manifest constants + simple templates + functions + version declarations + debug declarations * Handling identifiers that are D keywords * Replacement of C style declarations of pointers and arrays * Unnecessary forward references * More stringent typing enforcement * Array handling * Replacing C basic types with D types None of the following was necessary: * Reorganizing the code * Changing data or control structures * Changing the flow of the program * Changing how the program works * Changing memory management Future Now that it is in DasBetterC, there are lots of modern programming features available to improve the code: * [141]modules! * memory safety (including [142]buffer overflow checking) * metaprogramming * [143]RAII * Unicode * [144]nested functions * [145]member functions * [146]operator overloading * [147]documentation generation * [148]functional programming support * [149]Compile Time Function Execution * [150]etc. Action Let us know over at the [151]D Forum how your DasBetterC project is coming along! Share this: * [152]Tweet * * Categories [153]BetterC, [154]Code, [155]Core Team 4 thoughts on “DasBetterC: Converting make.c to D” 1. biocyberman says: [156]June 12, 2018 at 11:00 am Link to discussion on Dlang to save you some seconds: [157]https://forum.dlang.org/thread/nefesucwkczieolryaxb@forum.dlan g.org?page=1 [158]Reply 2. Niels Vilsk says: [159]June 22, 2018 at 7:51 pm Incredibly clear and pragmatic explanations on how any C programmer can progressively convert its C legacy software to the modern D language. Probably the best “D tutorial for C programmers” to date !!! [160]Reply 3. Rugxulo says: [161]August 24, 2018 at 5:01 pm Pardon the suggestion, but I think minised would be a good tool to convert. (I halfway wanted to convert it to Turbo Pascal [FPC] myself!) It’s BSD-licensed, has a good test suite, and is a standard POSIX tool. I often find sed very useful (even if I’m not really *nix savvy). [162]http://exactcode.com/opensource/minised/ [163]Reply 4. hen3ry says: [164]April 8, 2019 at 9:12 am I started on Dash (that is, Bash) as a training exercise. The C code is surprisingly clean. It does, however, use YACC, which I would replace with a Pratt parser solution in the Future. [165]Reply Leave a Reply [166]Cancel reply Your email address will not be published. Required fields are marked * Comment _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ Name * ______________________________ Email * ______________________________ Website ______________________________ Post Comment This site uses Akismet to reduce spam. [167]Learn how your comment data is processed. Post navigation [168]Previous Previous post: Driving Continuous Improvement in D [169]Next Next post: How an Engineering Company Chose to Migrate to D Content Copyright © 2016-2018 by the [170]D Language Foundation, All Rights Reserved References Visible links 1. https://dlang.org/blog/feed/ 2. https://dlang.org/blog/comments/feed/ 3. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/feed/ 4. https://dlang.org/blog/2018/06/02/driving-continuous-improvement-in-d/ 5. https://dlang.org/blog/2018/06/20/how-an-engineering-company-chose-to-migrate-to-d/ 6. https://dlang.org/blog/wp-json/oembed/1.0/embed?url=https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/ 7. https://dlang.org/blog/wp-json/oembed/1.0/embed?url=https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/&format=xml 8. https://dlang.org/menu.html 9. https://tour.dlang.org/ 10. https://dlang.org/documentation.html 11. https://dlang.org/spec/spec.html 12. https://dlang.org/phobos/index.html 13. http://dlang.org/dmd.html 14. https://dlang.org/comparison.html 15. https://dlang.org/articles.html 16. https://dlang.org/download.html 17. https://code.dlang.org/ 18. https://dlang.org/community.html 19. https://dlang.org/blog 20. http://dlang.org/orgs-using-d.html 21. https://twitter.com/search/q=#dlang 22. https://forum.dlang.org/ 23. irc://irc.freenode.net/d 24. https://wiki.dlang.org/ 25. https://github.com/dlang 26. http://dlang.org/bugstats.php 27. https://dlang.org/resources.html 28. https://wiki.dlang.org/Books 29. https://wiki.dlang.org/Tutorials 30. https://wiki.dlang.org/Development_tools 31. https://wiki.dlang.org/Editors 32. https://wiki.dlang.org/IDEs 33. http://rainers.github.io/visuald/visuald/StartPage.html 34. https://dlang.org/acknowledgements.html 35. https://dlang.org/dstyle.html 36. https://dlang.org/glossary.html 37. https://dlang.org/sitemap.html 38. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/#content 39. https://dlang.org/blog/ 40. https://dlang.org/ 41. https://forum.dlang.org/ 42. https://dlang.org/foundation/donate.html 43. https://www.zazzle.com/store/dlang_swag?rf=238129799288374326 44. https://www.zazzle.com/store/dlang_swag?rf=238129799288374326 45. https://www.zazzle.com/store/dlang_swag?rf=238129799288374326 46. http://dlang.org/blog/index.php/feed/ 47. http://dlang.org/blog/index.php/comments/feed/ 48. http://forum.dlang.org/group/general 49. https://github.com/dlang/D-Blog-Theme/issues 50. https://dlang.org/blog/the-d-and-c-series/ 51. https://dlang.org/blog/d-in-production/ 52. https://dlang.org/blog/symmetry-autumn-of-code/ 53. https://dlang.org/blog/the-gc-series/ 54. https://dlang.org/blog/2020/04/28/interfacing-d-with-c-arrays-and-functions-arrays-part-two/ 55. https://dlang.org/blog/2020/04/13/dustmite-the-general-purpose-data-reduction-tool/ 56. https://dlang.org/blog/2020/03/17/d-2-091-0-released/ 57. https://dlang.org/blog/2020/03/13/tracing-d-applications/ 58. https://dlang.org/blog/2020/02/17/news-update-swag-platforms-documentation-help-and-more/ 59. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/ 60. https://dlang.org/blog/author/walterbright/ 61. http://walterbright.com/ 62. http://digitalmars.com/ 63. http://www.classicempire.com/ 64. https://dlang.org/blog/the-d-and-c-series/#betterC 65. https://dlang.org/blog/2017/08/23/d-as-a-better-c/ 66. https://github.com/dlang/dmd 67. https://en.wikipedia.org/wiki/Datalight 68. https://digitalmars.com/ctg/make.html 69. https://github.com/DigitalMars/Compiler/commit/473bf5bef99a1748d5154b343b986534271cd841#diff-14c44b49b9f46b1aeab33a6684214e55 70. https://github.com/DigitalMars/Compiler/blob/1dbd3e3381c8f7f7ab2e35214dcd63455ae38c29/dm/src/make/dmake.d 71. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34 72. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R11 73. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R29 74. https://dlang.org/spec/module.html#import-declaration 75. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L23 76. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R20 77. https://dlang.org/spec/version.html#version 78. https://dlang.org/spec/version.html#predefined-versions 79. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R27 80. https://dlang.org/spec/attribute.html#linkage 81. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L27 82. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R499 83. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff–14c44b49b9f46b1aeab33a6684214e55L290 84. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R276 85. https://dlang.org/spec/version.html#DebugStatement 86. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L37 87. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L40 88. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R66 89. https://dlang.org/spec/enum.html#manifest_constants 90. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L42 91. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R68 92. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L56 93. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R74 94. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L45 95. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R82 96. https://dlang.org/spec/attribute.html#gshared 97. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R113 98. https://dlang.org/spec/declaration.html#alias 99. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R131 100. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L86 101. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L83 102. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R98 103. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L111 104. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R131 105. https://dlang.org/spec/declaration.html#declaration_syntax 106. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L159 107. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R191 108. https://dlang.org/spec/attribute.html#static 109. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L189 110. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L240 111. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L242 112. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L248 113. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L275 114. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L297 115. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L303 116. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R312 117. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L335 118. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L396 119. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R463 120. https://dlang.org/spec/lex.html#comment 121. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R503 122. https://dlang.org/spec/version.html#staticif 123. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L585 124. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L658 125. https://dlang.org/spec/const3.html#const_and_immutable 126. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R920 127. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1099 128. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R1160 129. https://dlang.org/spec/function.html#inout-functions 130. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1628 131. https://dlang.org/spec/arrays.html#array-properties 132. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1683 133. https://dlang.org/spec/lex.html#string_literals 134. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1688 135. https://dlang.org/spec/property.html#sizeof 136. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55R1692 137. https://github.com/DigitalMars/Compiler/commit/a25bee1ba3a3b5231fd80aa1b24aa18ce3eb3a34#diff-14c44b49b9f46b1aeab33a6684214e55L1773 138. https://github.com/DigitalMars/Compiler/commit/473bf5bef99a1748d5154b343b986534271cd841#diff-69c1b24ec5df3f3b5a5bb99bc60345f7 139. https://digitalmars.com/ctg/make.html 140. https://github.com/DigitalMars/Compiler/commit/7765879be1be6fcb3eb959d1598d8ff227c2b0af#diff-2bac52ea58e12548536bb246cced3af4 141. https://dlang.org/spec/module.html 142. https://dlang.org/spec/arrays.html#bounds 143. https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization 144. https://dlang.org/spec/function.html#nested 145. https://dlang.org/spec/class.html#member-functions 146. https://dlang.org/spec/operatoroverloading.html 147. https://dlang.org/spec/ddoc.html 148. https://dlang.org/spec/function.html#pure-functions 149. https://dlang.org/spec/function.html#interpretation 150. https://dlang.org/spec/spec.html 151. https://forum.dlang.org/group/general 152. https://twitter.com/share 153. https://dlang.org/blog/category/betterc/ 154. https://dlang.org/blog/category/code/ 155. https://dlang.org/blog/category/core-team/ 156. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/#comment-4679 157. https://forum.dlang.org/thread/nefesucwkczieolryaxb@forum.dlang.org?page=1 158. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/?replytocom=4679#respond 159. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/#comment-4773 160. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/?replytocom=4773#respond 161. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/#comment-5748 162. http://exactcode.com/opensource/minised/ 163. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/?replytocom=5748#respond 164. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/#comment-8866 165. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/?replytocom=8866#respond 166. https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/#respond 167. https://akismet.com/privacy/ 168. https://dlang.org/blog/2018/06/02/driving-continuous-improvement-in-d/ 169. https://dlang.org/blog/2018/06/20/how-an-engineering-company-chose-to-migrate-to-d/ 170. https://dlang.org/foundation.html Hidden links: 172. https://dlang.org/