Richard@houxk.UUCP (10/12/83)
This is a open request to this newgroup for information, opinions and examples. I am a casual user of Pascal and C. Recently, I read a Consultants report done by BBN for Lawrence Livermore Labs comparing and contrasting 4 different high level languages: Ada, Praxis, Pascal and C. The document is available as a DoD report. There were a few questions I had regarding recommendations of the report. 1) BBN said that the lack of a variant record structure in C was a serious weakness. I didn't feel that way based on my frequency of it's use in Pascal. Am I mistaken? Are there serious examples of places where it is ABSOLUTELY needed? 2) What is overloading? Ada is claimed to have too complicated a scope rule due to overloading. Could someone tell me in plain english what is overloading AND is it a frill? 3) What is the Pascal mechanism used by the compiler to implement the display mechanism? As I understand it, the display is a way for a called procedure to determine the values of a caller procedures local variables. It seems to be a secondary stack whose contents are those stack addresses at which the starting addresses of each procedure frame resides. Is this correct. If so, do compilers allocate this secondary stack pointer (display stack pointer) as a general purpose register (e.g. %r3 of VAX-11/180) or in a fixed memory address? 4) One unrelated but interesting question: Is a negative growing stack frame discipline better or worse than positive growing stack frame discipline? Is a ngs discipline re-traceable or reconstructable if the stack frame gets broken during run time? Is there a public domain recovery procedure for ngs short of killing the process? Regards, (No Flames please, just illumination) Richard Trauben AT&T Bell Labs (201) 949-0088
leichter@yale-com.UUCP (Jerry Leichter) (10/12/83)
Overloading, as the term is used in ADA, refers to the use of a single symbol to denote a number of different functions, depending on the types of its arguments. Thus, in some languages, the "+" in a+b could be integer addition, real addition, or even string concatenation, depending on whether a and b were integers, reals, or strings. Because of its multiplicity of types, and the mechanisms it provides for the user to define new types and extend existing (or new) operators to them, ADA makes a bigger issue of overloading than earlier languages - although the idea has obviously been around since at least FORTRAN. I find the argument that "C doesn't have varient records" strange. It does; that's what unions are. What it doesn't have is the ability to have the compiler insert varient-dependent code for you, as PASCAL and some other languages do. This isn't surprising, since the ability to make any sense of such automatic code insertion seems inextricably bound up with a stricter type mechanism than C supports - i.e. this criticism seems to be just another way of saying "C doesn't have strong typing". I know of no reason to suppose that there is any difference between negative and positive growing stack disciplines EXCEPT in cases where you want to grow the stack dynamically in a paged environment, want to be able to allocate less than a full page to the stack, AND your hardware doesn't support the right kind of limitation. This is vague; here's a concrete example. On 11's and VAXes, stacks grow downward (toward smaller memory locations) and pages are 512 bytes. Suppose I want a 256-byte stack (or a k*512+256 byte stack; it's the same issue) and I want the memory mapping hardware to give me an interrupt when I overflow. So I have to map 256 bytes. No problem; on almost any machine, I can map the bottom 256 bytes of the page, and start the stack at the last mapped word. When the stack overflows the bottom of the page, I'll know about it. Problem: Suppose I want to extend the stack. I can do this by adding a WHOLE other page with addresses BELOW the bottom of what I already have, but I cannot re-use the upper half of my already- mapped page, nor is there any way to add less than a whole new page - unless I'm willing to move the existing stack. This problem does not arise on an 11 or VAX, since I can tell the memory mapping hardware to map the TOP 256 (or whatever) bytes of a page, rather than the BOTTOM ones, if I want. Such downward-growing pages are typically used exactly for stack space. BTW, you left out another distinction I can make in maintaining stacks, independently of growth direction: Does the stack pointer point to the last element put on the stack, or the the next element to be put there? On the 11, stack manipulation is based on the auto-increment and auto- decrement addressing modes. Thus mov item,-(r1) *r1-- = item push item (oops, wrote the C backwards! should be: *--r1 = item mov (r1)+,item item = *r1++ pop item This implements a downward-growing stack in which the stack pointer (r1) points to the top item on the stack. It works that way because -(r1) is a PRE-decrement, but (r1)+ is a POST-increment. I could just as well have done: mov item,(r1)+ *r1++ = item push item mov -(r1),item item = *--r1 pop item That would implement an upward-growing stack in which the stack pointer points to the "next" item. The downward-growing stacks used by just about all 11 and VAX code are essentially a matter of convention - a convention strongly encouraged by the hardware, which uses it for its own stack manipulation (on subroutine calls and interrupts) and the various operating systems. -- Jerry decvax!yale-comix!leichter leichter@yale
mark@cbosgd.UUCP (Mark Horton) (10/14/83)
C not only has variant records (e.g. unions), but it is possible to
have DYNAMIC sized records, of a sort. E.g.
struct string {
short length;
char body[1];
} *p;
...
p = malloc(sizeof (struct string) + strlen(str));
p->length = strlen(str);
strcpy(p->body, str);
Try doing THAT in Pascal!
A display is not part of the Pascal Language. It's a technique a
compiler writer can use in a block structured language to implement
block structure. It's basically an array of frame pointers, one
for each level of static scoping. There are other implementations,
for example the P compiler uses a "static link" to the stack frame
of the next static level - to reference a variable 3 levels out,
you follow a chain of static pointers of length 3. There is a special
pointer for global variables, since they are a common case. In
ordinary Pascal programs that aren't nested very deep, this works
reasonably well, but in a deeply nested program a display can be
much much faster.