Tuesday, 27 January 2015

C Programming - Common mistakes while using the "if" statement

This post demonstrates common mistakes while using the if statement. The recent IDEs and compilers issues a warning if the code encounters such mistakes. One way to resolve such mistakes is to force the IDEs and compilers to show warnings as errors. This way you can build your application more robust.

if -


The if statement is used to check a condition and if the condition is true, we run a block of statements (called if-block), else we process another block of statements (called the else-block). The else clause is optional.

 

Mistake 1: Using the assignment operator = instead of the relational operator ==


int main()
{
     int i;
     printf("Enter value of i ");
     scanf("%d", &i);
     if (i = 10)
          printf("You entered 10");
          else
             printf("You entered other than 10");
     return 0;
}
/*output:
Enter value of i 499
You entered 10
Enter value of i 9999
You entered 10 
*/
 

 Every time the output is You entered 10. This is because of

using assignment operator = instead of relational operator ==.
So whatever value you supply, the above program prints You entered 10. In C, other than zero is considered as TRUE in if statement. So the program prints You entered 10.


How to Resolve?


This mistake can be easily avoid by interchanging the variable and constant in a if statement.
Write the condition like this if(10 = a) , so you will receive the compiler error, you cannot assign a variable to a constant.

 

Mistake 2: if statement followed by a semicolon (;)


Consider the following program.
int main()
{
     int i;
     printf("Enter value of i ");
     scanf("%d",&i);
     if (i == 10);
          printf("You entered 10");
     return 0;
}
/*output:
Enter value of i 499
You entered 10
Enter value of i 9999
You entered 10 
*/
 

The ; makes the compiler to interpret the statement as follows -

if (i == 10)     
;
printf("You entered 10");
 
consider the condition returns true;
the ; (null statement, which does nothing on execution) gets executed, following the printf() gets executed.
Consider the condition returned false;
then straight-away the printf() gets executed.
Thus, irrespective of whether the condition evaluates to true or false the printf() gets executed. Both example one and two contain so-called semantic errors. This type of error is also called logical errors and is not discovered by the compiler when the syntax is correct. Therefore, there is a plethora of tools you can use to examine the source code before going ahead and compile it.


How to Resolve?


You can resolve these mistakes using the Splint tool.
Splint is a tool for statically checking C programs for security vulnerabilities and coding mistakes. With minimal effort, Splint can be used as a better lint. If additional effort is invested adding annotations to programs, Splint can perform stronger checking than can be done by any standard lint.
For more details on Splint - Click here

Please share your thoughts on this post in the comments section.

Karthik Byggari

Author & Editor

Computer Science graduate, Techie, Founder of logicallyproven, Love to Share and Read About pprogramming related things.

2 comments:

  1. Both example one and two contain so-called semantic errors. This type of error is also called logical errors and is not discovered by the compiler when the syntax is correct. Therefore, there is a plethora of tools you can use to examine the source code before going ahead and compile it.

    For example, Example 1 compiles without any errors even though i is assigned a value instead to be compared against something. But a control of the source code with splint provides among others the following warning:

    (I've cut some of the output to point out the importent stuff according to the error):

    splint tst.c
    Splint 3.1.2 --- 03 May 2009

    ... // Some of the output is removed

    tst.c:8:10: Test expression for if is assignment expression: i = 10
    The condition test is an assignment expression. Probably, you mean to use ==
    instead of =. If an assignment is intended, add an extra parentheses nesting
    (e.g., if ((a = b)) ...) to suppress this message. (Use -predassign to
    inhibit warning)
    tst.c:8:10: Test expression for if not boolean, type int: i = 10
    Test expression type is not boolean or int. (Use -predboolint to inhibit
    warning)

    First we can see that the test expression is an assignment, which was not the intention. It is syntactically correct but semantically wrong. So the compiler will let the statement through but splint gives a warning to be aware of.

    A check of the source code with splint gives the warning:

    ...@pmb:~/Cprog$ splint tst.c
    Splint 3.1.2 --- 03 May 2009

    // Some output is removed for clarity

    tst.c:8:19: Body of if statement is empty
    If statement has no body. (Use -ifempty to inhibit warning)

    The "body of if statement is empty", that should call our attention.

    This was just a hint to make coding and debugging a little bit easier. You can read more about lint and splint at the Internet.


    ReplyDelete

 
biz.