ddmdgdcldc

Do ldc and gdc support D language contracts?


This code with a contract:

import std.stdio;

int TestContract(int a)
in
{
   assert( a > 0);
}
do
{
   return a + 1;
}

int main(string[] args)
{
   auto a = 2;
   try
   {
      writeln(a," + 1 is ",TestContract(a));
      a = -2;
      writeln(a," + 1 is ",TestContract(a));
   }
   catch (Exception e)
   {
      writeln(e);
   }
   return 0;
}

compiles and runs with dmd (v2.076.0-dirty), but not ldc (0.17.1) or gdc ( 5.4.0 20160609).

ldc says:

contracts.d(12): Error: declaration expected, not 'do'
contracts.d(15): Error: unrecognized declaration

and gdc says:

contracts.d:12:1: error: declaration expected, not 'do'
 do
 ^
contracts.d:15:1: error: unrecognized declaration
 }

Edit: Compiling with "body" instead of "do", per the answer succeeds with ldc. gdc gets a new compile error:

/usr/include/d/core/stdc/stdarg.d:48:5: error: undefined identifier __va_list_tag
     alias __va_list = __va_list_tag;

Note that at the present time the dlang.org documentation for contract programming does not mention that body, while likely deprecated, still works, and is necessary for versions of the dmd compiler earlier than [unknown version] and any versions of gdc or ldc that use a dmd front-end before version [unknown version].


Solution

  • Use body, not do. Allowing do instead of body is a very recent thing (I wasn't aware that that change had even been accepted, though it compiles with the current dmd, so I guess it was).

    dmd, ldc, and gdc all share the same frontend, but they don't all have the same version. Even if you're using the most recent ldc, it's at least one, maybe two releases behind dmd, and unless you're using a development version of gdc, it's currently way behind (it's at 2.068 IIRC, whereas dmd 2.077.0 is in beta at the moment), though the next release they do should finally be fairly close to dmd (the frontend switch from C++ to D caused major delays for them).