Shared pain

Jason House jason.james.house at gmail.com
Fri Nov 19 05:25:17 PST 2010


A cast to immutable is required when constructing immutable objects. The type system can't prove that's safe. It's a design limitation to keep complexity low.

http://www.digitalmars.com/d/2.0/phobos/std_regexp.html
Looking at the Regexp docs, find isn't marked const or pure. If that's an oversite, file it in bugzilla. If it can't be const, then you should find another approach.

When this stuff crashes for you, is it accessing a different thread's TLS or is it simply unable to handle TLS at all?

Steve Teale Wrote:

> On Thu, 18 Nov 2010 11:26:39 +0000, Steve Teale wrote:
> 
> > I had D code that provided a basis for creation of Windows services,
> > which I have just tried to get working with the latest D2.
> > 
> > No dice.
> > 
> I have made some progress in understanding this. It appears that any D 
> static data structures containing function pointers will now cause a 
> Windows service to crash.
> 
> For happiness, these must be forced into the global data segment.
> 
> I have demonstrated this within a vestigial service for a couple of cases 
> - plain old struct containing an int and a function pointer, and for 
> Regexp objects by using and not using __gshared on the offending objects.
> 
> Now that I'm reasonably sure what's happening, I ought to be able to make 
> these things work by making such static members immutable, and 
> initializing them in static this().
> 
> However, I then run into a slew of complier errors. Lets start with this 
> simple framework:
> 
> import std.stdio;

> import std.regexp;

> 

> class ThingWithStatic

> {

>    static RegExp rex;

>    string ns;

> 

>    static this()

>    {

>       rex = RegExp("ab+a");

>    }

> 

>    this()

>    {

>       ns = "abbaabba";

>    }

> 

>    int getFromStatic() { return rex.find(ns); }

> }

> 

> void main()

> {

>    ThingWithStatic tws = new ThingWithStatic();

>    writefln("%d", tws.getFromStatic());

> }
> 
> This compiles fine, but if I include this class in a service, and call 
> getFromStatic(), the service will crash. If I change to:
> 
> __gshared RegExp rex;
> 
> It compiles fine, and the service does not crash.
> 
> If I change to:
> 
>    static immutable RegExp rex;
> 
> Then I get errors:
> 
> triv.d(11): Error: cannot implicitly convert expression (opCall("ab
> +a",null)) of type std.regexp.RegExp to immutable(RegExp)
> triv.d(19): Error: function std.regexp.RegExp.find (string string) is not 
> callable using argument types (string) immutable
> steve at Ubuntu:~/scratch$
> 
> So then I use a cast:
> 
> rex = cast(immutable(RegExp)) RegExp("ab+a");
> 
> and get down to:
> 
> triv.d(19): Error: function std.regexp.RegExp.find (string string) is not 
> callable using argument types (string) immutable
> 
> as somewhat wierd message in itself. So I use a cast in the call to find
> ():
> 
>  return (cast(RegExp) rex).find(ns);
>  
>  At this point it compiles, and if it's used in the service, the service 
> does not crash.
>  
>  BUT - all these complicated casts will be extremely tedious to 
> administer to code that uses RexExp methods all  over the place, so 
> __gshared is a great temptation. The compiler should try to eliminate 
> such temptations in the interests of safety.
>  
> Also why are these casts necessary. If I am assigning to something that 
> is the same type and was declared as immutable should not at least the 
> first cast be done implicitly. In the second case, I'm using a Regexp 
> object, wherever it may be stored, so why the cast? If find was pure 
> would the cast still be required?
> 
> Thanks
> Steve



More information about the Digitalmars-d mailing list