static this sucks, we should deprecate it

Steven Schveighoffer schveiguy at yahoo.com
Thu May 28 11:48:53 PDT 2009


On Thu, 28 May 2009 14:23:48 -0400, Ary Borenszweig <ary at esperanto.org.ar>  
wrote:

> Steven Schveighoffer wrote:
>> On Thu, 28 May 2009 13:59:10 -0400, Ary Borenszweig  
>> <ary at esperanto.org.ar> wrote:
>>
>>> Is there something wrong in my reasoning?
>>  It's just that you aren't always compiling every file at the same  
>> time...
>> Static this' implementation isn't part of the public interface, so it  
>> might not even *be* in the import file (if it's a .di file).
>
> So it should be in the .di file.
>
>    Where do
>> you throw the compiler error, if you can't determine the circular  
>> reference at comiple time?
>
> You don't throw the error and that's it. What's the worse thing that  
> could happen? A bug in the code. You go and you fix it. If there's no  
> bug in the code and the compiler yells at you, that's very annonying  
> (like in the example you showed).

A bug like this could be very subtle, you may not know the order static  
this' are executed.  Worse than that, simply importing another module  
could affect the order, and that might make an unrelated bug that  
previously was hidden suddenly show up.

>
>>  I think with the import system the way it is, the only safe prospect  
>> is to have it error like it does now.  You either need some attribution  
>> like has been suggested in this thread (and have the compiler verify  
>> that attribution), or change the import system.
>
> I still can't see what's the problem if the error were not issued by the  
> compiler and static this would be run in the order defined by  
> dependencies found in static ifs.

I assume you mean static this'?

>
> Until I see a real example where if the compiler doesn't issue an error  
> then something *really bad* would happen, then I won't be able to give  
> much more opinion about this. :-(

What about this (bear with me, lots of files here):

f1.d:
private import f2;
int x;

static this()
{
   x = y;
}

f2.d:
private import f3;

int y;

static this()
{
   y = z;
}

f3.d:
private import f1;

int z;

static this()
{
   z = x;
}

Now, the compiler has to obey 3 rules: f1 depends on f2, f2 depends on f3,  
f3 depends on f1.

Oops, there's a cycle, but we can detect that, right?

What if you are importing .di files:

f2.di:

int y;

static this();

Now, how do you know when compiling f1 that it depends on f3, and f3  
depends on f1?  The cycle is hidden because the compiler can't look at the  
compiled end result for each source file.

This is similar to the "how come the compiler can't automatically decide  
what's const and what's not" debate.  Unless the compiler is allowed to  
generate metadata from files that it can feed back into itself later,  
these kinds of things are impossible without manual annotation.

I realize the end result of my example is pretty innocuous, but imagine  
that you are trying to use an object you expect to be instantiated by a  
static this function, only to find that it's null.

I'd rather see a "circular import" error than a segfault that all of a  
sudden shows up because someone used my library differently.

-Steve



More information about the Digitalmars-d mailing list