[M3devel] reference to globals in globals?

Rodney M. Bates rodney_bates at lcwb.coop
Thu Aug 16 19:27:17 CEST 2012



On 08/15/2012 07:55 PM, Hendrik Boom wrote:
> On Wed, Aug 15, 2012 at 09:51:41AM -0500, Rodney M. Bates wrote:
>>
>>
>> On 08/14/2012 10:04 PM, Jay K wrote:
>>>
>>> Heck, even if these weren't global, is it that unreasonble,
>> >from the programmer's point of view, for the language/compiler
>>> to do some pointer escape analysis and let me take the address
>>> of a local, as long as I don't store it somewhere that outlives
>>> the local?
>>>
>>
>> This is ultimately an undecidable problem and even conservative
>> approximations of reasonable sophistication are far too involved
>> for a language to require of every compiler.
>
> Not to mention the obscurityof the language definition.
>

Yes, yes, yes!!!

> But isn't there something like that with the addresses of top-level
> proocedures?  the ones whose environments are completely static?
> Or am I thinking of another type-safe language?  Or am I thinking of
> assigning the procedures themselves?

Yes.  If you can assign a procedure (or pointer to function, which is
equivalent, for this discussion) to a variable, then there are ways to
call the procedure when its environment does not exist, i.e, one or
more scopes of variables that the procedure is declared inside of and
can refer to.  The outermost scope always exists, so we need three
nested scopes to get an example.

MODULE Outer

; PROCEDURE Middle ( MiddleFormal : INTEGER )

   = PROCEDURE Inner ( ) : INTEGER

     = BEGIN
         RETURN MiddleFormal
       END

   ; BEGIN (* Middle *)
       ProcVar := Inner (* Statically illegal because Inner is not top-level. *)
     END (* Middle

; VAR ProcVar : PROCEDURE ( ) : INTEGER
; VAR X : INTEGER

; BEGIN (* Outer *)
     Middle ( 7 )
   ; X := ProcVar ( )
   END Outer
.

If the assignment ProcVar := Inner were legal, the call ProcVar ( )
goes to Inner, which refers to MiddleFormal of Middle, but there is no
active invocation of Middle, and MiddleFormal doesn't exist.

Pascal (if I remember all this right) allows procedures to be passed
as parameters, but not assigned to variables.  The procedure constant
in question can only be named where it has an environment.  If all you
can do with it is pass it, any use of it can only be deeper inside the
dynamic call chain, where its environment continues to exist.

Modula-2 allows procedures to be either passed or assigned, but in
either case, only a top-level procedure, which always has an
environment, can be given.

Both passing and assigning procedures have reasonable uses, both for
variations on the callback theme.

Modula-3 supports both by allowing any procedure to be passed but only
a top-level one to be assigned.  Enforcing the latter restriction
sometimes means a runtime check at the point of an assignment, if the
RHS of the assignment is a procedure formal parameter, which could
dynamically be top-level or not.  This is probably not a
high-frequency situation.  Assigning a procedure constant and passing
any procedure can be fully checked at compile time.

I think it is possible to define a weaker, yet safe rule that
postpones runtime environment existence checking until the point of a
call on a procedure variable, but I don't recall seeing this in any
language.  Maybe Algol68 or something.

In gcc-enhanced C, which allows nested functions, in addition to both
assigning and passing (pointers to) functions, you are on your own to
avoid calling something that lacks an environment.  The one help the
language gives is to say in the reference, "all hell will break loose"
if you get this wrong.


>
> -- hendrik



More information about the M3devel mailing list