-1

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 ?

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
user1086516
  • 887
  • 3
  • 9
  • 21
  • Sure. You have some functions and/or data in one file, and some in another, and some in another, etc. You compile the files independently. Then you link them together to produce a single executable file that can be run. Once a program is sufficiently large, you pretty much have to split it into multiple files to keep it manageable, in any programming language. – Tom Karzes Feb 25 '19 at 08:42
  • Aren't you describing separate compilation ? I am asking for an example of non-separate compilation which I assume was a feature of languages predating C which I have no experience with. – user1086516 Feb 25 '19 at 08:45
  • The "C Book" mentions Algol. So reading up on Algol should provide with a few examples. – StoryTeller - Unslander Monica Feb 25 '19 at 08:46
  • 3
    In that case, your question is unclearly worded. You quote from a C book where separate compilation is described, and Algol is mentioned as a language in which it is harder, but you just asked for examples of "programming in this nature". Why would people assume you wanted an Algol example? The natural assumption is that you wanted examples of separate compilation in C, as can be seen from the responses. – Tom Karzes Feb 25 '19 at 08:49
  • @user1086516 you have answers with separate and non separate compilations, is that you asked ? – bruno Feb 25 '19 at 09:28
  • How could I possibly ask for something when I don't what it is called ? The author goes on to explain separate compilation, which is how every normal programming language works implying that a) there is a different way to do things and b) the fact that C was capable of doing so separate compilation was significant. – user1086516 Feb 25 '19 at 09:49
  • @user1086516 is bruno's answer what you need? He shows an example of separate compilation and another one of non separate compilation. Your latest comment doesn't make it any clearer. – Jabberwocky Feb 25 '19 at 10:00
  • @user1086516 we are several trying to understand your question and trying to answer. But I am lost with your last remark, I don't know if you got or not your answer. If we are several to not answer well that means we cannot understand you because you are not clear enough in your question ... – bruno Feb 25 '19 at 10:05
  • I am asking in the history of programming when was this: "In C we are free to put all in one file or in several files and also to compile in one or several steps" NOT the case. I am struggling to understand when you could NOT do this and it was a big deal that C could. – user1086516 Feb 25 '19 at 10:10
  • 2
    @user1086516, separate compilation was always a feature of some languages; it wasn't introduced by C. Some languages in the Algol family did not provide it, for instance Pascal, but it always was a popular extension. – AProgrammer Feb 25 '19 at 10:17
  • @AProgrammer Thank you. Knowing that I was easily able to find the paper: "Separate Compilation and Partial Specification in Pascal" which explains exactly the historical context I was missing. – user1086516 Feb 25 '19 at 10:26
  • @user1086516 your question speak about all source in one file or not, and about sources files compiled separated or not and about linking, and your question finishes by _Can anyone provide some basic examples / overview of programming in this nature_. This is **exactly** what I speak about in my answer ! You say you speak about _history_ , where is that word in your question ? Can you explain how we can give _basic examples_ of history ? Non sense – bruno Feb 25 '19 at 10:26

4 Answers4

1

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

   begin
   int x; x:=3;

   procedure p;
       begin
       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;
              print(z)
              end;

       q(1)
       end;

    p; comment a parameterless procedure call;
    end;

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.

0

Smallest example of non separate compilation, the alone file m.c containing :

int main() {}

compilation : gcc m.cproducing the executable a.out


In C we are free to put all in one file or in several files and also to compile in one or several steps, if this is your question

Example with 2 functions in the alone file m.c :

#include <stdio.h>

void hw()
{
   puts("hello world");
}

int main()
{
   hw();
}

Compilation, we are also free to do in one or several steps

  • gcc m.c producing the executable a.out
  • or gcc -c m.c producing m.o then gcc m.o producing executable a.out

Same program using several files, hw.c containing

#include <stdio.h>
#include "hw.h" /* not mandatory in current case but recommended to check signature compatibility */

void hw()
{
   puts("hello world");
}

and hw.h containing

#ifndef _HW_H
#define _Hw_H
extern void hw();
#endif

and m.c containing

#include "hw.h"

int main()
{
   hw();
}

Compilation, using one or several steps :

  • gcc m.c hw.c producing executable a.out
  • or gcc -c m.c hw.c producing objects m.o and hw.o, then gcc m.o hw.o to produce executable a.out
  • or gcc -c m.c producing objects m.o then gcc -c hw.c producing object hw.o then gcc m.o hw.o to produce executable a.out

It is also possible to create and use a library, here a static library containing only hw.o :

  • gcc -c m.c hw.c producing objects m.o and hw.o (or two gcc commands, one by object)
  • ar rcs hw.a hw.o to make the static library containing hw.o
  • gcc m.o hw.a to produce the executable a.out
bruno
  • 32,421
  • 7
  • 25
  • 37
0

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

Have one file called add.c that contains the following code:

int add(int a, int b){
    return a+b;
}

Compile it with:

gcc -c add.c

This creates add.o. Now have a file with following code called main.c:

#include <stdio.h>
int add(int, int); // declares "add", but doesn't implement it!

int main( int argc, char **argv){
    printf("3 + 2 = %d\n", add(3,2));
    return 0;
}

This declares add, but doesn't implement it. It won't run on its own. But you can still compile it with

gcc -c main.c

And then you can link them with:

gcc add.o main.o 

If you run the resulting program (might be called a.exe` or something similar) you will get the following result:

3 + 2 = 5

The advantage of this is that you can modify one of the parts, recompile it, then link it again without having to touch the other parts. If you want a more detailed explanation on the matter, I recommend reading this answer.

Blaze
  • 16,736
  • 2
  • 25
  • 44
0

I am not sure what the book means with "The block structure of the Algol-like languages makes this harder by insisting that the whole program comes in one chunk." But I can imagine that an Algol-like language allows or requires that functions and procedures are declared within the main program block, implying that there is only one program block and this will not allow partitioning the program in compilable units, as C does. But again, I don't know what the book means with that statement.

Hypothetical example:

AlgolMain
Begin
    procedure x
    Begin
        ....
    End
    ....
End
Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • I think this hits the nail squarely on the head. The Revised Algol60 Report defines ``` ::= | ``` so there can be nothing outside the outermost **begin** - **end** pair. –  May 28 '19 at 22:53