Jump to content
xisto Community
bhavesh

C Pitfalls Discuss the loopholes in C

Recommended Posts

The C language is terse and expressive. There are few restrictions to keep the user from blundering. In this topic we will find out the pitfalls and try to find out what should be done to run a C program.

 

I will begin with the basic mistake programmers do (Obviosly due to there work-load) and its consequence.

 

= is not ==

 

Programming languages derived from Algol, such as Pascal and Ada, use := for assignment and = for comparison. C, on the other hand, uses = for assignment and == for comparison. This is because assignment is more frequent than comparison, so the more common meaning is given to the shorter symbol.

 

Moreover, C treats assignment as an operator, so that multiple assignments (such as a=b=c) can be written easily and assignments can be embedded in larger expressions.

 

This convenience causes a potential problem: one can inadvertently write an assignment where one intended a comparison. Thus, this statement, which looks like it is checking whether x is equal to y:

 

if (x = y)foo();
Actually sets x to the value of y and then checks whether that value is nonzero. Or consider the following loop that is intended to skip blanks, tabs, and newlines in a file:

 

while (c == ’ ’ || c = ’\t’ || c == ’\n’)c = getc (f);
The programmer mistakenly used = instead of == in the comparison with ’\t’. This ‘‘comparison’’ actually assigns ’\t’ to c and compares the (new) value of c to zero. Since ’\t’ is not zero, the ‘‘comparison’’ will always be true, so the loop will eat the entire file. What it does after that depends on whether the particular implementation allows a program to keep reading after it has reached end of file. If it does, the loop will run forever.

 

Some C compilers try to help the user by giving a warning message for conditions of the form e1 = e2. To avoid warning messages from such compilers, when you want to assign a value to a variable and then check whether the variable is zero, consider making the comparison explicit. In other words, instead of:

 

if (x = y)foo();
write:

 

if ((x = y) != 0)foo();
This will also help make your intentions plain.

 

It is easy to miss an inadvertent substitution of = for == because so many other languages use = for comparison. It is also easy to interchange & and &&, or | and ||, especially because the & and | operators in C are different from their counterparts in some other languages.

 

 

Multi-character Tokens


Some C tokens, such as /, *, and =, are only one character long. Other C tokens, such as /* and ==, and identifiers, are several characters long. When the C compiler encounters a / followed by an *, it must be able to decide whether to treat these two characters as two separate tokens or as one single token. The C reference manual tells how to decide:

 

‘‘If the input stream has been parsed into tokens up to a given character, the next token is taken to include the longest string of characters which could possibly constitute a token.’’

 

Thus, if a / is the first character of a token, and the / is immediately followed by a *, the two characters begin a comment, regardless of any other context.

 

The following statement looks like it sets y to the value of x divided by the value pointed to by p:

 

y = x/*p /* p points at the divisor */;
In fact, /* begins a comment, so the compiler will simply gobble up the program text until the */ appears. In other words, the statement just sets y to the value of x and doesn’t even look at p. Rewriting this statement as

 

y = x / *p /* p points at the divisor */;
or even

 

y = x/(*p) /* p points at the divisor */;
would cause it to do the division the comment suggests.

 

This sort of near-ambiguity can cause trouble in other contexts. For example, older versions of C use =+ to mean what present versions mean by +=. Such a compiler will treat

 

a=-1;

as meaning the same thing as

 

a =- 1;

or

 

a = a - 1;

This will surprise a programmer who intended

 

a = -1;

On the other hand, compilers for these older versions of C would interpret

 

a=/*b;

as

 

a =/ * b ;

even though the /* looks like a comment.


Before posting anything more I would like to know whether anybody is interested in this topic or not ?

Notice from truefusion:
Information copied from off a PDF file: http://www.literateprogramming.com/ctraps.pdf Added quotes. Warning issued.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.