digitalmars.D.learn - DateTime trying to do it at compile time.
- Mr. Jonse (14/14) Oct 26 2017 C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(2395):
- Rene Zwanenburg (22/26) Oct 26 2017 I suspect you're trying to instantiate your class in a static
- Jonathan M Davis (36/54) Oct 26 2017 It's very black and white with CTFE. The compiler never does CTFE unless...
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
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
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