www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - SysTime bug or feature?

reply tchaloupka <chalucha gmail.com> writes:
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 ()
Oct 05 2015
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
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
Oct 05 2015
parent tchaloupka <chalucha gmail.com> writes:
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.
Oct 05 2015