How Nested Functions Work, part 1

Jarrett Billingsley jarrett.billingsley at gmail.com
Wed Sep 2 12:43:24 PDT 2009


On Wed, Sep 2, 2009 at 3:29 PM, Don<nospam at nospam.com> wrote:
> Michiel Helvensteijn wrote:
>>
>> Rainer Deyke wrote:
>>
>>>> I still find it silly that it was built that way. Seems to me you should
>>>> be able to forward-reference *any* symbol that has a value that can't
>>>> change over its lifetime. Functions, const/immutable vars, typedefs,
>>>> classes, etc.
>>>
>>> That can lead to subtle problems in the case of functions:
>>>
>>> int i = f();
>>> int f() { return i; }
>>
>> You're right, I forgot about that. You can conservatively statically
>> forbid
>> this. But I admit it makes the 'constant data should obviously be
>> forward-referenceable' thing less convincing. :-)
>>
> I can't see how it can be done in the general case, other than by
> constructing a dependency tree of top-level symbols.
> Pass over the tree, evaluating everything which is a leaf of the tree.
> If you have a pass where you don't succeed in removing any leaf nodes, you
> have a circular dependency.
> DMD sort of does this, I think, but it only does two passes, and it's not
> very good at backing out when it discovers something is not a leaf.
> It'd be hard to make that efficient when there are potentially infinite
> passes.

It wouldn't even be that difficult. Basically if you treat
forward-referenced nested functions as a sort of goto, the same rules
should apply: a call to a nested function may not skip the
initialization of any variables it depends on. When i's initializer is
evaluated, it has not been declared yet, so the call to f is illegal.
It also prevents other invalid use.



More information about the Digitalmars-d mailing list