Old code no longer working on any DMD compilers

Jamie notme at gmail.com
Fri Sep 6 05:59:30 UTC 2019

On Friday, 6 September 2019 at 00:41:12 UTC, Jonathan M Davis 
> On Thursday, September 5, 2019 6:24:07 PM MDT Jamie via 
> Digitalmars-d-learn wrote:
>> /home/jamie/.dvm/compilers/dmd-2.077.0/linux/bin/../../src/phobos/std/math
>> .d(3702): Error: fmodl cannot be interpreted at compile time, 
>> because it
>> has no available source code called from here: called from 
>> here:
>> fmod(cast(real)to(n),
>> cast(real)to(2))
>> Thanks
> Based on that implementation, fmod would work at compile time 
> if you compile on Windows and use Microsoft's runtime instead 
> of Digital Mars runtime (so, if it was compiled as 64-bit or it 
> used whatever the flag is to force the COFF format instead of 
> OMF for 32-bit). It won't work on any other platform at compile 
> time, because core.stdc.math.fmodl is a C function, and C 
> functions cannot be called at compile time.
> By any chance were you compiling this on Windows previously 
> rather than Linux? If so, that's likely why the code worked 
> before and doesn't now. If you were always compiling on Linux, 
> then I don't know why you were able to compile your code 
> before. A quick glance at the repo history shows that fmod has 
> had that same implementation since 2012, so there should be no 
> way that it was callable on any Linux system even 6 years ago, 
> let alone 6 months ago.
> - Jonathan M Davis

Thanks for the reply. I haven't used Windows in the past two 
years so that isn't the issue in my case. After your comments I 
looked deeper, and I think my issue is related to compile time 
values, and me misunderstanding default arguments for structs.

import std.stdio;
import std.conv: to;
import std.math: fmod;

void main()
     /// without default arguments
     S s = S(64, 64);            // case 1: works
     // static S s = S(64, 64);     // case 2: doesn't work

     /// with default arguments
     // static S s = S();           // case 3: works

struct S
     this(size_t N, size_t M) {
     // this(size_t N=64, size_t M=64) {
         f(N, M);

void f(size_t N, size_t M)
     int kj(int n)
         return to!int(fmod(n, 2));
     int k = kj(2);

If I'm understanding it correctly now, in case 1 the struct 
constructor isn't called at compile time, so the underlying C 
function (fmod) is not called. In case 2 because the struct is 
called in a static region, the constructor is called at compile 
time and fmod is called so it breaks. In case 3, with default 
struct arguments, I thought that the constructor I have defined 
was being called, however the default constructor was being 
called (this()) so fmod wasn't being called.

The reason why my old code worked was because it used the default 
arguments and I wasn't actually calling the constructor I 
defined. When I removed the default arguments in the constructor 
and tried case 2 it obviously didn't work.

Am I understanding correctly? Thanks

More information about the Digitalmars-d-learn mailing list