#[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 <stdio.h> 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/