1

I am reading Ken Thompson's Reflections on Trusting Trust and have come across a piece of example code that I don't quite understand (Figures 3.*).

Figure 3.1:

compile(s)
char *s;
{
    ...
}

Figure 3.2:

compile(s)
char *s;
{
    if (match(s, "pattern")) {
        compile("bug");
        return;
    }
    ...
}

Figure 3.3:

compile(s)
char *s;
{
    if (match(s, "pattern1")) {
        compile("bug1");
        return;
    }
    if (match(s, "pattern2")) {
        compile("bug2");
        return;
    }
    ...
}

What is the meaning of char s[]; after compile(s)?

Also, why is there a block of code that doesn't belong to a function initialisation or if/else/while/do statement?

Daniel Schütte
  • 578
  • 1
  • 6
  • 20

2 Answers2

4

This is an old, obsolete syntax for declaring the type of the parameters of a function. You declare the types of the parameters after the line that contains the name of the function and its parameters, but before the opening brace that starts the body of the function.

compile(s)
    char *s;
{
    /* function body goes here */
}

The reason for this weird syntax is that it evolved from B, a predecessor of C, which did not have any type declarations: a variable was a machine word (a “cell”), and it was up to the programmer to use it correctly. See “The Problems of B” in “The Development of the C language” by Dennis Ritchie. With no types, to define a function, you'd just write

compile(s)
{
    /* function body goes here */
}

In early C, parameter declarations were optional, so existing code kept working. If something's type wasn't declared, it defaulted to int.

This declaration syntax is part of the first version of the C language, called K&R C after the authors of the seminal book about C, Brian Kernighan and Dennis Ritchie. In the late 1980s and 1990s, there was a gradual move to a newer version of the language called ANSI C or C89 or C90 (1989 and 1990 are the years the ANSI and ISO standards specifying the new version of the language came out). One of the main changes of ANSI C was in how function parameters are declared. In post-1990 C, you declare the type of parameters directly inside the parentheses, and you also declare the return type of the function (this is mandatory since C99, although many compilers still assume int if the return type is omitted).

int compile(char *s)
{
    /* function body goes here */
}
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
3

That is the K&R style of declaring the type of an argument.

The function named compile takes an argument named s, whose type is char [] and returns an int.

Most likely it is old code.

These days one would use something like this

int compile(char *s)
{
}
EvilTeach
  • 28,120
  • 21
  • 85
  • 141
  • @JohnBollinger In the linked paper, there are no semicolons, so this answer is right. I'm upvoting. – tos-1 Jul 28 '19 at 12:48
  • @tos, the answer is **wrong** for the question as posed, but I have reversed my DV after realizing that the question does not accurately quote the source. – John Bollinger Jul 28 '19 at 12:49
  • @JohnBollinger That is indeed true. However, I think it is the answer to what OP meant. :) – tos-1 Jul 28 '19 at 12:53
  • @tos-1, it doesn't much matter what the OP meant if what he actually asked is unmistakably different. What happens when someone else comes by, sees the question in its present form, and thinks this answer responds correctly to that? – John Bollinger Jul 28 '19 at 12:55
  • @john. What do you perceive as being wrong? – EvilTeach Jul 28 '19 at 15:04
  • @EvilTeach, this answer is no longer wrong, the question since having been edited. In its original form, however, the question *did not* present a K&R-style function definition, but rather just invalid code. – John Bollinger Jul 28 '19 at 17:07