www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - DateTime trying to do it at compile time.

reply Mr. Jonse <Your email.address> writes:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(2395): 
Error: variable lock cannot be modified at compile time
C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(2422):   
      called from here: initOnceLock()
C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(2422):   
      called from here: initOnce(delegate shared(bool)() => 
init(), initOnceLock())
C:\D\dmd2\windows\bin\..\..\src\phobos\std\datetime\timezone.d(1128):       
called from here: initOnce(delegate shared(bool)() => (*function () => true)())
C:\D\dmd2\windows\bin\..\..\src\phobos\std\datetime\timezone.d(583):       
called from here: (*& singleton)()
C:\D\dmd2\windows\bin\..\..\src\phobos\std\datetime\systime.d(64):       
called from here: opCall()

when calling Clock.currTime() in a this() in a class. I have no 
idea why it is trying to do it at compile time and failing. I 
thought if ctfe couldn't compile it would do it at run time 
anyways? Seems like a bug.
Oct 26 2017
next sibling parent Rene Zwanenburg <renezwanenburg gmail.com> writes:
On Thursday, 26 October 2017 at 17:55:05 UTC, Mr. Jonse wrote:
 when calling Clock.currTime() in a this() in a class. I have no 
 idea why it is trying to do it at compile time and failing. I 
 thought if ctfe couldn't compile it would do it at run time 
 anyways? Seems like a bug.
I suspect you're trying to instantiate your class in a static context, which causes it to be constructed at compile time. For example: ==== class A { this() { // Do sth. with datetime } } class B { // This will construct A at compile time. This also // means a single A instance is shared between all // B instances. This is different from most langs! A a = new A; } // This will also construct at compile time. A moduleScopedA = new A; ==== The solution is to new A in your class or module constructor.
Oct 26 2017
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, October 26, 2017 17:55:05 Mr. Jonse via Digitalmars-d-learn 
wrote:
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(2395):
 Error: variable lock cannot be modified at compile time
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(2422):
       called from here: initOnceLock()
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(2422):
       called from here: initOnce(delegate shared(bool)() =>
 init(), initOnceLock())
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\datetime\timezone.d(1128):
   called from here: initOnce(delegate shared(bool)() => (*function () =>
 true)())
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\datetime\timezone.d(583):
   called from here: (*& singleton)()
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\datetime\systime.d(64):
 called from here: opCall()

 when calling Clock.currTime() in a this() in a class. I have no
 idea why it is trying to do it at compile time and failing. I
 thought if ctfe couldn't compile it would do it at run time
 anyways? Seems like a bug.
It's very black and white with CTFE. The compiler never does CTFE unless it has to (e.g. you're initializing a enum, or you're directly initializing a static variable or member variable). So, it's not going to do CTFE as an optimization anywhere (though a number of folks mistakenly think that it will). And if it does CTFE, then CTFE must succeed. The compiler is never going to decide that something failed at CTFE, so it will just do it at runtime instead. It's doing CTFE, because it requires a result that must be known at compile time. So, clearly, the class that calls Clock.currTime in its constructor is being constructed at compile time, which isn't going to work, because Clock.currTime accesses the system's C API to get the time (and you almost certainly wouldn't want the time the code was compiled anyway). I'd guess that Rene's suggestion is correct and that you're directly initializing a member variable somewhere that's of this class type. It's either that or you're directly initializing a module-level variable, a static variable, or an enum of that class type - _or_ you're doing something else at CTFE that ultimately calls a function that is constructing an instance of one of these classes. Ultimately, you either need to not be constructing an instance of this class at compile time, or you need to make it so that it will work at compile time without getting the current time (or doing anything else that can't be done at compile time). if(__ctfe) {} can be used to create branches that do something different during CTFE so that they can function during CTFE even though they would normally do something that wouldn't work during CTFE (e.g. if you have an algorithm that uses pointer arithmetic for performance, you could provide an alternate implementation for compile time that was slower, because it didn't use pointer arithmetic, but at least it would then work at compile time). I'd guess though that in this case, you're simply directly initializing a variable whose value must be known at compile time, in which case, the solution would likely be to not directly initialize it. - Jonathan M Davis
Oct 26 2017