Path: utzoo!utgpu!water!watmath!clyde!rutgers!iuvax!pur-ee!uiucdcs!uxc.cso.uiuc.edu!uxe.cso.uiuc.edu!mcdonald
From: mcdonald@uxe.cso.uiuc.edu
Newsgroups: comp.lang.c
Subject: Re: Variable function names
Message-ID: <47000025@uxe.cso.uiuc.edu>
Date: 14 Dec 87 15:56:00 GMT
References: <973@russell.STANFORD.EDU>
Lines: 59
Nf-ID: #R:russell.STANFORD.EDU:973:uxe.cso.uiuc.edu:47000025:000:3076
Nf-From: uxe.cso.uiuc.edu!mcdonald    Dec 14 09:56:00 1987


>> 
>> Is there an equivalent in C for the "funcall" utility (in Lisp)?
>> I wasn't able to find any information about variable functions that can
>> be called in any of the C manuals.  I'd appreciate any pointers/advice/
>> alternatives on how to go about doing this.
>> 
>> 						-- Vallury

>C will allow you to refer to previously-compiled functions indirectly
>(through function pointers), but the feature you're talking about can
>only be implemented in an interpretive language like Lisp.  Lisp will
>interpret commands as it encounters them, and hence a Lisp object can
>be used both as code and data.  For example, if you define a list in
      (section omitted)

>This will not work in C or in any compiled language such as Pascal,
>FORTRAN, COBOL, etc. etc., as these compile their code and keep their
>data separate from the code.

>Now, you could write, in C, a program that implements an interpreter
>that will take in character strings and execute them per some set of
>rules.  In fact, there are several implementations of Lisp that are
>written in C.  The unix shells are also examples of programs that are
>implemented in C and that are interpretive.


>So the point here is that in C, you can't do exactly what you described, and
>this is due to the fact that C is compiled, not interpreted.

Apparently C does not allow this as a general, required, feature. However,
I learned C with the explicit assumption that, since it allowed both
data and function pointers, one could take an array, write a program that
generated compiled code in that array, cast the address of (the first
byte of) the array to a function pointer, and call that function. 
     I have since learned that on some systems (i.e. 80286 Xenix in anything
except single-segment model) it won't work, and that ANSI C does not
require it to work (A FATAL FLAW). BUT, on all the machines that I regularly
use, including the VAX/VMS, PDP-11/Decus-C, IBM-PC/DOS, and IBM-PC/OS2,
it does work (although on OS2 it requires a minor help from a system call.)
     Just because a language is normally compiled, as C is, does not mean
that you can't write an interpreter in it (for the language of your choice),
or, as I have done, an incremental compiler. It's just that on your
particular system, the system implementer has stupidly prevented you from
executing the code you generate. Any system in which is is impossible to
write something as obvious as an incremental compiler is terminally
brain-damaged. (Actually, in most cases it can be done with the aid of
assembly language.)
     Would someone explain to me why a system would prevent you from doing
this? You couldn't have a TurboPascal or even a Forth! (I wouldn't object
if you had to explicitly declare that a block of memory would be both
data and code.)

Doug McDonald

P.S. Please don't think I've done anything as ambitious as write a complete
language compiler. My little affair is a simple incremental compiler for
arithmetic expressions only. I first tried an interpreter, but the compiler
was faster by about a factor of 75.