Examples of non-separate compilation?

From section 1.1 of "The C Book":

At the coarsest level, an obvious feature is the multi-file structure of a program. The language permits separate compilation, where the parts of a complete program can be kept in one or more source files and compiled independently of each other. The idea is that the compilation process will produce files which can then be linked together using whatever link editor or loader that your system provides. The block structure of the Algol-like languages makes this harder by insisting that the whole program comes in one chunk, although there are usually ways of getting around it.

Can anyone provide some basic examples / overview of programming in this nature ?


  • Example Algol program, which does nothing useful but is here to illustrate the point:

       int x; x:=3;
       procedure p;
           integer y; y:=4;
           procedure q(n);
              value n; integer n;
              if n > 0
              then q(n-1)
              else begin
                  integer z; z:=x+y;
        p; comment a parameterless procedure call;

    The basic problem here is nested scopes. The procedure q depends on the surrounding blocks that define integers x and y. The procedure p likewise depends (by virtue of containing q) on the block that defines x.

    You'll see, then, that each part of this stupid example program is inseparable from the surrounding text. This is the natural mode of expression to Algolers; to nest procedures in a way that makes sense for the program being written. In general this makes separate compilation quite complicated. This differs from C-like languages which have no nested procedures (functions, whatever) because the only non-local identifiers they can refer to are file scope or global scope (if I have those terms correct).

    Here, the variables x and y are local to some procedure and are therefore on the stack. Just to make it more complicated, q is recursive, which makes the "distance down the stack" from its innermost invocation to the locations of x and y a variable quantity, so it's not just a matter of compiling a fixed value off some stack-frame pointer.

    Nevertheless, there were some systems that allowed separate compilation. As far as I recall, there were restrictions, such as the unit of compilation (a file, if you like) having to contain only procedures 'at the top level'. They might also have needed some extended syntax (like 'external procedure foo') to tell the compiler that something being referenced was not expected to be defined in the current file.