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