Shared pain

Steve Teale steve.teale at britseyeview.com
Thu Nov 18 22:53:40 PST 2010


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