Debug 101 – C

Introduction:

Here are listed common mistakes people have when programming in C.

Programs are compiled as follows: gcc -std=c11 -Wall source.c -o program

Programs are executed as follows: ./program

The format of this document is:

  • Problem description
  • Code snippet (example of faulty code)
  • Compiler output
  • Fix

 

General tips and reccommendations

Check compiler errors and warnings

After compiling the program always check compiler errors, warnings and notes. Should you have many problems with your code always start fixing the first problem – this is because some bugs depend on the previous bugs.

Consult with man pages / cplusplus library

If you are using linux you can open terminal and use man pages to look for a function you wish to know more of. E.g. you want to find more information about scanf then you type „man scanf ”However if you don’t see programs instead of library functions add 3 after man (this lists library functions – for more info type „man man”) e.g.  „man 3 printf ”. Man pages are really helpful when you are unsure which parameters functions take and which libraries should be included to the project.

For some googling might be more comfortable then 2 sites for the same purpose are recommended: http://www.cplusplus.com/reference/clibrary/ and  http://linux.die.net/man/3/ .

Common mistakes

Undeclared variables

Example:

undec_code

Compiler Output:

undec_compiler

Fix:

Declare variable named ’sum’ before using it to add x and y values.

Uninitialized variables

Example:
uninit_codeCompiler Output:

uninit_compiler

Program Output:

uninit_out

Fix:

When you declare a variable you get a random memory address for the variable which might be filled with garbage data. Therefore it is recommended to initialize variables to ensure correct output.

In this case x and y should be initialized to 0 in order to get output of 10 + 0 + 0 = 10. ’sum’ may be uninitialized because it will get the value from magical number ’10’ and variables ’x’ and ’y’

Single equal sign to check equality

Example:

eq_code

Compiler Output:

eq_compiler

Fix:

In comparison statements use two equal signs ’==’ to compare values.

In current example program will keep asking for user input even if input is not ’y’.

Undeclared functions

Example:

undef_fun

Compiler Output:

undec_fun_compiler

Fix:

Either move the function declaration before main function or create a prototype of the function before main function. In this example prototype would be:

void say_hello();

No Semicolons

Example:
nosemi_code
Compiler Output:

nosemi_compiler

Fix:

Add semicolon after printf function call.

Extra semicolons

Example:

exsemi_code

Compiler Output:

No messages are shown.

Fix:

Since compiler does not give any messages you should be extra careful with these kind of errors.  Program will output 100 however counting from 0 to 99 was desired.

Fix this problem by removing semicolon after for loop.

Overstepping boundaries

Example:

bounds_code

Compiler Output:

No messages are shown.

Program Output:

bounds_out

Fix:

Remember that computers count from 0 thus in this example first item in array is at 0 and last at 2.

Misusing && and || operators

Example:

operator_code

Compiler Output:

No messages are shown.

Program Output:

Program keeps printing „Grade: 5” even though grade is 5. To get a better understanding why this occurs please refer to boolean algebra and its operators OR / AND.

Fix:

Replace while loop condition with: „!(grade == 4) && !(grade == 5)” this way program will loop until the grade is either 4 or 5.Note that this can also be achieved with „!((grade == 4) || (grade == 5))”. In this example there are many more ways to loop until grades are not 4 or 5 however they are not shown.

Integer division

Example:

div_code

Compiler Output:

div_compiler

Program Output:

div_out

Fix:

To solve this problem it is useful to think about the application. The example on line 25 is not reccommended because data loss may occur. All of the data after decimal point is truncated. Integers cannot be displayed with real value placeholder e, f, g or lf  hence 0 is shown. In order to display values without data loss integers either need to be typecasted to double / float or according datatypes should be used for division (double / float). Note that real values are written with „.” e.g. 5.6.

Scope of variable

Example:

scope_code

Compiler Output:

scope_compiler

Fix:

The scope of variable i is for loop. This means that variable i can only be used within the loop. If using variable i after loop is desired then variable declaration should be before for loop. Don’t forget to initialize variable as well!

Switch breaks

Example:

switch_code

Compiler Output:

No messages are shown.

Program Output:

switch_out

Fix:

In order to avoid executing every case after desired case, break statements should be used. In this example if after every printf function call was break; then only „Could do better.” would be displayed. However sometimes this kind of behaviour is desired but it is out of the scope of this course. Note that break statement can also be used to exit loops before the end condition of loop is met.

Loop conditions and actions in loop

Example:

loops_inf

Compiler Output:

No messages are shown.

Program Output:

Infinitely prints the formatted string.

Fix:

Assign value to result in the loop so that eventually it will become greater than 99.

Example:

loops_inf_code_bottles

Compiler Output:

No messages are shown.

Fix:

Check the initialization and actions done every loop. Probably the desired result would require initial bottles value of 100 and decrementing bottles value every loop. The other desired result could be with loop condition that checks whether bottles is less than 100. Always verify loop initialization, condition and post loop actions.

Wrong formatted print/scan placeholders

Example:

format_code

Compiler Output:

No messages are shown.

Program Output:

format_out

Fix:

On line 25 correct placeholder was used for scanning character (%c) however when printing the user input, integer placeholder (%d) was used instead. When this is done with characters a matching number is displayed (see ASCII table). To fix this use %c on line 26.

 

Sources

3 thoughts on “Debug 101 – C

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.