12 Common C Errors

From EDM2
Jump to: navigation, search

In this list I'll cover 12 common pitfalls that are made in C. The check-list is meant as a tool for beginners.

  1. Remember to start and end comments correctly
    Comment begin: /*
    Comment end: */
  2. The assignment operator '=' is often mistaken for the test operator '=='
    This mistake is easy to make since many other programming languages use '=' as a test operator. The compiler may not discover this type of error since the assignment has a value and therefore is legal in an expression. An example is:
    if (number = 9)
    number = 0;
    'number' is assigned the value 0 since the 'number = 9' assignment always returns a true value.
  3. Errors with assignments in statements
    Missing brackets around assignments causes errors that the compiler wont be able to find.
    Example:
    while (ch = getchar() != EOF)
    'ch' will here be assigned the value 1 for TRUE until 'getchar()' returns EOF, where 'ch' is assigned the value 0 for FALSE. The correct statement:
    while ((ch = getchar()) != EOF)
  4. Errors with arrays
    In C the lowest array-index is zero, i.e. the following declaration:
    int myArray[10];
    sets up 10 elements myArray[0], myArray[1], ..., myArray[9]. Example:
    for (i=0; i <= 10; i++)
    myArray[i] = i;
    Since C doesn't have runtime-checks of array boundaries, this example will cause the variable myArray[10] to be assigned a value. But since myArray[10] hasn't been declared another variable will be overwritten. [...If there is another variable in memory right after the array. Lack of bound checking is the cause of many security holes in networking software. Ed].
  5. Remember brackets when calling a function without parameters
    Example:
    x = square; /* incorrect */
    and
    x = square(); /* correct */
    Note: Depending on what compiler you have you will get a compiler error from the line above.
  6. Errors by transferring a pointer to a function
    If the function 'convert' is declared as
    void convert(int *px);
    where the parameter is a pointer to an integer, the function has to be called with a pointer as parameter. Example:
    int result;
    convert(&result);
    The typical error is caused by omission of the address operator '&'
  7. Remember to declare functions
    If functions returns other values than the 'int' type, they have to be declared before they are called. Example:
    long a;
    a = getlong();
    In this case 'a' is assigned an 'int' instead of a 'long'. In order to be correct the function has to be declared like this (also called prototyped):
    /* The void is not necessary, but good practice */
    long getlong(void);
    long a;
    could also be declared like this [confusing style though. Ed]:
    long a, getlong(void);
  8. Remember 'break' in the 'switch' construct
    If you forget a 'break', the program will continue until it meets another 'break' or the end of the 'switch' block has been reached. Example:
    switch (weekday) {
    case MONDAY : printf("Start a new week");
    case TUESDAY: /* no break here */
    case FRIDAY :
    workday++;
    break;
    default: weekday++;
    }
    If you start with MONDAY you will also execute the TUESDAY and FRIDAY code because there is no break until after FRIDAY, which means that default wont be executed unless weekday is different from MONDAY, TUESDAY or FRIDAY.
    If there are statements executed with several entrances like in the example above, and break is left out on purpose, it should be commented.
  9. Use of side effects in expressions
    The use of side effects in expressions can cause unpredictable programs. Example:
    a[n] = n++;
    is equivalent either to:
    a[n] = n;
    n = n + 1;
    or to:
    a[n + 1] = n;
    n = n + 1;
    Which case holds depends on the compiler.
  10. Errors with type conversions
    Type conversion of a 'char' to an 'int' or a right shift of an 'int' can be done with or without a 'sign extension'.
    [Which happens depends on how the compiler is implemented. Ed]
  11. Remember brackets with pointers and increment/decrement operators
    Example:
    char line[80];
    *lp = line;
    ch = *lp++; /* the same as *(lp++) */
    In this example 'ch' is assigned what 'lp' is pointing at after which lp is incremented.
    ch = (*lp)++;
    In this example 'ch' is assigned what 'lp' is pointing at, but in this case it's the value that 'lp' is pointing at that's incremented.
  12. Watch out that you don't confuse the logical operators (&&, ||) with the bit operators (&, |)

This article is based on material collected by Finn Overgaard Hansen DTI 1993.