Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with this 1988 C code?

Tags:

c

I'm trying to compile this piece of code from the book "The C Programming Language" (K & R). It is a bare-bones version of the UNIX program wc:

#include <stdio.h>  #define IN   1;     /* inside a word */ #define OUT  0;     /* outside a word */  /* count lines, words and characters in input */ main() {     int c, nl, nw, nc, state;      state = OUT;     nl = nw = nc = 0;     while ((c = getchar()) != EOF) {         ++nc;         if (c == '\n')             ++nl;         if (c == ' ' || c == '\n' || c == '\t')             state = OUT;         else if (state == OUT) {             state = IN;             ++nw;         }     }     printf("%d %d %d\n", nl, nw, nc); } 

And I'm getting the following error:

$ gcc wc.c  wc.c: In function ‘main’: wc.c:18: error: ‘else’ without a previous ‘if’ wc.c:18: error: expected ‘)’ before ‘;’ token 

The 2nd edition of this book is from 1988 and I'm pretty new to C. Maybe it has to do with the compiler version or maybe I'm just talking nonsense.

I've seen in modern C code a different use of the main function:

int main() {     /* code */     return 0; } 

Is this a new standard or can I still use a type-less main?

like image 501
César Avatar asked Dec 27 '11 03:12

César


People also ask

What are the C standards?

C standard may refer to: ANSI C, C99, C11, C17, or C2x, specifications of the C programming language. C standard library. C tuning (guitar), a type of tuning for guitars.

How c is created?

A successor to the programming language B, C was originally developed at Bell Labs by Ritchie between 1972 and 1973 to construct utilities running on Unix. It was applied to re-implementing the kernel of the Unix operating system. During the 1980s, C gradually gained popularity.

Does C have a runtime?

The venerable C language uses a runtime environment -- the C compiler inserts runtime instructions into the executable image (the compiled .exe file). The runtime instructions create runtime environments that can manage the processor, handle local variables and so on throughout the program's execution.

What language is C written in?

So, C is not written in any language. The C language is a set of rules defined on the language specification. In order for a C program run in your machine it is “translated” into binary. The compiler is responsible for that.


2 Answers

Your problem is with your preprocessor definitions of IN and OUT:

#define IN   1;     /* inside a word */ #define OUT  0;     /* outside a word */ 

Notice how you have a trailing semicolon in each of these. When the preprocessor expands them, your code will look roughly like:

    if (c == ' ' || c == '\n' || c == '\t')         state = 0;; /* <--PROBLEM #1 */     else if (state == 0;) { /* <--PROBLEM #2 */         state = 1;; 

That second semicolon causes the else to have no previous if as a match, because you are not using braces. So, remove the semicolons from the preprocessor definitions of IN and OUT.

The lesson learned here is that preprocessor statements do not have to end with a semicolon.

Also, you should always use braces!

    if (c == ' ' || c == '\n' || c == '\t') {         state = OUT;     } else if (state == OUT) {         state = IN;         ++nw;     } 

There is no hanging-else ambiguity in the above code.

like image 122
user7116 Avatar answered Oct 03 '22 05:10

user7116


The main problem with this code is that it is not the code from K&R. It includes semicolons after the macros definitions, which were not present in the book, which as others have pointed out changes the meaning.

Except when making a change in an attempt to understand the code, you should leave it alone until you do understand it. You can only safely modify code you understand.

This was probably just a typo on your part, but it does illustrate the need for understanding and attention to details when programming.

like image 34
jmoreno Avatar answered Oct 03 '22 07:10

jmoreno