Ten C Programming Mistakes

I’m certain that more than 10 C programming mistakes are common, but for some reason people enjoy lists with 10 items. My list of Ten C Programming Mistakes isn’t a top-ten list, so nothing is ranked. These are just a collection (cut off at 10) of the problems and issues I find most frequently when coding in the C language.

Matching Braces and Parentheses

This mistake isn’t a problem, providing that you use a source code editor that highlights braces, parentheses, and square brackets. Even then, you may ignore this issue, wonder why the one brace is highlighted, and attempt to compile.

If you format your code consistently, finding a missing brace is easy. Ditto for finding a missing parentheses, which is why I try to add spaces around functions as arguments and other complex statements.

Forgetting Semicolons

This issue has cropped up for me recently, and probably for other coders as well, especially when I switch between C and other languages that don’t bother with statement terminating characters. In C. all statements end with a semicolon. Newer languages, such as Python and Swift, don’t require a terminating character. So when you return to C, you may find yourself coding without adding the semicolon. Fortunately, a smart text editor goes bonkers when you forget the semicolon. The compiler is also good about flagging this oversight.

Misplacing a Semicolon

Just as you might forget a semicolon at the end of a statement, you may accidentally add a semicolon after an if or while condition, as in:

if( a == b );

Or:

while( x < 66 );

Such a thing is permissible and often necessary. The clang compiler flags such statements as a warning, but the preferred format is:

while( x < 66 )
    ;

When not flagged, such stray semicolons can lead to hours to bug-hunting.

Using = instead of ==

This booboo happens in most programming languages: The = is the assignment operator. The == is a comparison operator, which is why I pronounce it "is equal to" as opposed to "equals." Even then, I still mess up and use = for a comparison. Fortunately, the clang compiler is good about flagging this mistake.

Signed Integers in Loops

A signed integer flips from positive to negative, wrapping around and eventually incrementing back to zero. If you use a signed integer in a loop, and you're expecting an unsigned value to terminate the loop, you've just created an endless loop.

For example, say you're using a char variable to loop from 0 to 200:

#include <stdio.h>

int main()
{
    char x;

    for(x=0;x<200;x++)
        printf("%d ",x);
    putchar('\n');

    return(0);
}

The for loop in this code is eternal. In fact, the clang compiler generates a warning because signed char variable x can only hold the value 127 before it "increments" to -128.

Forgetting a Loop's Exit Condition

Specifically with a while loop, some statement within the loop must alter the exit condition. If you forget to, say, modify variable x for while(x<66), the loop never ends. Rare is the loop that doesn't require an exit condition.

Not Terminating a String

A string must terminate with the null character, \0. All C string library functions maintain the null character terminator. Strings you declare in your code obey this rule. It's only when you mess with a string on your own that you can forget about the null character terminator. When you do, chaos ensues.

Forgetting to Initialize a Pointer

Not only pointers, but every variable type in C must be initialized before it's used. In C, variables are declared and allocated in two steps. It would nice if every variable declared were initially allocated to zero or NULL, but that's just not the case. It's up to you, Mr. C Coder, to initialize a variable, especially pointers.

Manipulating Pointers in Functions

Unlike other arguments passed to a function, a pointer's value cannot be manipulated within the function itself. This concept is weird, but understanding how it works helps you to avoid trouble: A pointer is memory address and you can access and use that address within a function, but you cannot change the address. To change the address, you must pass a pointer-pointer, or the address of the pointer, instead of its value directly. This solution is correct, but it adds a higher level of complexity to the code.

Writing Pointers to a File

When storage is allocated and assigned to a pointer, and that storage is written to a file, you must remember to write the storage itself and not the pointer variable. The pointer is a (typically) 4-byte address. Too many coders send that 4-byte address to a file and wonder why the file doesn't contain the contents desired. Write the pointer's contents, the stuff stored in memory, and not the pointer variable.

Leave a Reply