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