Thread overview
SysTime bug or feature?
Oct 05, 2015
tchaloupka
Oct 06, 2015
Jonathan M Davis
Oct 06, 2015
tchaloupka
October 05, 2015
This code:

import std.stdio;
import std.datetime;

void main()
{
    SysTime t = SysTime.init;
    writeln(t);
}

results in segfault with dmd-2.068.2

Is it ok?

Backtrace:

#0  0x00000000004733f3 in std.datetime.SysTime.adjTime() const ()
#1  0x00000000004730b9 in std.datetime.SysTime.toSimpleString() const ()
#2  0x0000000000473339 in std.datetime.SysTime.toString() const ()
#3  0x0000000000463dc4 in std.format.formatObject!(std.stdio.File.LockingTextWriter, std.datetime.SysTime, char).formatObject(ref std.stdio.File.LockingTextWriter, ref std.datetime.SysTime, ref std.format.FormatSpec!(char).FormatSpec) ()
#4  0x0000000000463cb7 in std.format.formatValue!(std.stdio.File.LockingTextWriter, std.datetime.SysTime, char).formatValue(std.stdio.File.LockingTextWriter, ref std.datetime.SysTime, ref std.format.FormatSpec!(char).FormatSpec) ()
#5  0x0000000000463c5a in std.format.formatGeneric!(std.stdio.File.LockingTextWriter, std.datetime.SysTime, char).formatGeneric(std.stdio.File.LockingTextWriter, const(void)*, ref std.format.FormatSpec!(char).FormatSpec)---Type <return> to continue, or q <return> to quit---
 ()
#6  0x0000000000463b63 in std.format.formattedWrite!(std.stdio.File.LockingTextWriter, char, std.datetime.SysTime).formattedWrite(std.stdio.File.LockingTextWriter, const(char[]), std.datetime.SysTime) ()
#7  0x0000000000463675 in std.stdio.File.write!(std.datetime.SysTime, char).write(std.datetime.SysTime, char)
    ()
#8  0x0000000000463591 in std.stdio.writeln!(std.datetime.SysTime).writeln(std.datetime.SysTime) ()
#9  0x0000000000461b38 in D main ()


October 06, 2015
On Monday, October 05, 2015 18:12:06 tchaloupka via Digitalmars-d-learn wrote:
> This code:
>
> import std.stdio;
> import std.datetime;
>
> void main()
> {
>      SysTime t = SysTime.init;
>      writeln(t);
> }
>
> results in segfault with dmd-2.068.2
>
> Is it ok?

It is by design, albeit undesirable. When SysTime was originally written, it was impossible to have a default value for a class reference other than null. So, unless SysTime was going to take the performance hit of constantly checking whether its TimeZone was null, SysTime.init was going to segfault if you did anything with it that required its TimeZone. And I wasn't about to have it constantly checking for null. In the vast majority of cases, the value of a SysTime comes from Clock.currTime() or from parsing a string, and if code is trying to do anything but assign to a SysTime which is SysTime.init, then that means that it failed to initialize it like it should have.

At some point in the last couple of years, it became possible to directly initialize a class reference that was a member variable (or static, or at module level, etc.) with an immutable class object. So, when the issue that you're bringing up was brought up last year, I tried to create a new TimeZone class that would specifically be for SysTime.init so that SysTime.init would still be unique (so that st is SysTime.init would still work properly), and it would print out "SysTime.init" for toString and be treated as 00001-01-01T00:00:00+00:00 for most everything else, but a compiler bugs with regards to Rebindable made it so that it didn't work.

I need to take another stab at it and see if it works now, but until the compiler issue is resolved, SysTime.init will continue to segfault if you do anything with it which requires its TimeZone to be used (which includes toString).

- Jonathan M Davis

October 06, 2015
On Tuesday, 6 October 2015 at 05:54:44 UTC, Jonathan M Davis wrote:
> It is by design, albeit undesirable. When SysTime was originally written, it was impossible to have a default value for a class reference other than null. So, unless SysTime was going to take the performance hit of constantly checking whether its TimeZone was null, SysTime.init was going to segfault if you did anything with it that required its TimeZone. And I wasn't about to have it constantly checking for null. In the vast majority of cases, the value of a SysTime comes from Clock.currTime() or from parsing a string, and if code is trying to do anything but assign to a SysTime which is SysTime.init, then that means that it failed to initialize it like it should have.

Thanks for thorough explanation.
I found the problem using vibe and REST API with SysTime argument with default value (which didn't work due to the bug there) when I tried to print out the passed value and ended up with the segfault. So I guess it doesn't bite devs often as it is mostly used as you wrote.