Types of Errors in C
Master debugging! Learn all error types: Syntax, Semantic, Linker, Runtime, Logical, and Unreachable Code errors with examples and fixes.
Track Your Progress
Sign in to save your learning progress
What You Will Learn
- ✓Identify different types of errors in C
- ✓Understand when each error type is detected
- ✓Fix common syntax, runtime, and logical errors
- ✓Recognize and remove unreachable code
- ✓Use compiler warnings to catch bugs early
Every programmer encounters errors — they're a natural part of learning and development. Understanding different types of errors helps you debug faster and write more reliable code. In this tutorial, we'll explore all error types in C with practical examples.
Why Understanding Errors Matters
- •Faster debugging: Know where to look when something goes wrong
- •Better code: Avoid common mistakes before they happen
- •Confidence: Error messages become helpful, not scary
Classification of Errors
When Are Errors Detected?
While compiling
Combining files
While running
Earlier detection = Easier to fix ✓
Syntax Errors
Grammar mistakes
Missing ; or )Semantic Errors
Meaning mistakes
Wrong type usedLinker Errors
Missing definitions
undefined referenceRuntime Errors
Crashes while running
Segmentation faultLogical Errors
Wrong output
Bug in algorithmUnreachable Code
Dead code warning
Code after return| Error Type | When Detected | Detected By | Difficulty to Fix |
|---|---|---|---|
| Syntax Error | Compile Time | Compiler | Easy |
| Semantic Error | Compile Time | Compiler | Medium |
| Linker Error | Link Time | Linker | Medium |
| Runtime Error | Execution | OS/Program | Hard |
| Logical Error | Output Analysis | Programmer | Hardest |
| Unreachable Code | Compile Time (Warning) | Compiler | Easy |
1. Syntax Errors (Compile-Time Errors)
Syntax errors occur when you violate the grammar rules of C. The compiler cannot understand your code and refuses to compile it. These are the easiest to fix because the compiler tells you exactly where the problem is.
Common Syntax Errors:
Missing Semicolon
1#include <stdio.h>23int main() {4 int x = 5 // ERROR: Missing semicolon!5 printf("x = %d", x);6 return 0;7}Undeclared Variable
1#include <stdio.h>23int main() {4 y = 10; // ERROR: 'y' was never declared!5 printf("%d", y);6 return 0;7}Mismatched Brackets
1#include <stdio.h>23int main() {4 if (5 > 3) {5 printf("Five is greater");6 // ERROR: Missing closing brace!7 return 0;8}Correct Version
1#include <stdio.h>23int main() {4 int x = 5; // Semicolon added5 int y; // Variable declared6 y = 10;7 8 if (5 > 3) {9 printf("Five is greater");10 } // Closing brace present11 12 return 0;13}2. Semantic Errors
Semantic errors occur when the syntax is correct but the meaning doesn't make sense. It's like saying "I ate the color blue" — grammatically correct but meaningless.
Type Mismatch
1#include <stdio.h>23int main() {4 int num = "Hello"; // Assigning string to int!5 6 float price = 10.5;7 int *ptr = price; // Assigning float to pointer!8 9 return 0;10}Wrong Number of Arguments
1#include <stdio.h>23void greet(char *name, int age) {4 printf("Hello %s, age %d\n", name, age);5}67int main() {8 greet("Alice"); // Missing second argument!9 return 0;10}3. Linker Errors
Linker errors occur after compilation, when the linker tries to combine object files. Usually caused by missing function definitions or multiple definitions.
Undefined Reference
1#include <stdio.h>23void sayHello(); // Declaration only, no definition!45int main() {6 sayHello(); // Linker can't find the function body!7 return 0;8}Fix: Add Function Definition
1#include <stdio.h>23void sayHello(); // Declaration45int main() {6 sayHello();7 return 0;8}910// Function definition added11void sayHello() {12 printf("Hello, World!\n");13}4. Runtime Errors
Runtime errors occur while the program is running. The code compiles successfully, but crashes or behaves unexpectedly during execution. These are harder to debug because they depend on specific conditions.
Division by Zero
1#include <stdio.h>23int main() {4 int a = 10;5 int b = 0;6 7 int result = a / b; // CRASH! Division by zero!8 9 printf("Result: %d\n", result);10 return 0;11}Array Out of Bounds
1#include <stdio.h>23int main() {4 int arr[5] = {1, 2, 3, 4, 5};5 6 // Valid indices: 0, 1, 2, 3, 47 printf("%d\n", arr[10]); // Index 10 doesn't exist!8 9 arr[100] = 999; // Writing to invalid memory!10 11 return 0;12}Null Pointer Dereference
1#include <stdio.h>2#include <stdlib.h>34int main() {5 int *ptr = NULL;6 7 *ptr = 100; // CRASH! Can't write to NULL address!8 9 return 0;10}How to Prevent Runtime Errors
1#include <stdio.h>2#include <stdlib.h>34int main() {5 int a = 10;6 int b = 0;7 8 // Check before dividing9 if (b != 0) {10 int result = a / b;11 printf("Result: %d\n", result);12 } else {13 printf("Error: Cannot divide by zero!\n");14 }15 16 // Check array bounds17 int arr[5] = {1, 2, 3, 4, 5};18 int index = 3;19 if (index >= 0 && index < 5) {20 printf("arr[%d] = %d\n", index, arr[index]);21 }22 23 // Check malloc result24 int *data = malloc(sizeof(int) * 10);25 if (data != NULL) {26 data[0] = 5;27 free(data);28 } else {29 printf("Memory allocation failed!\n");30 }31 32 return 0;33}5. Logical Errors
Logical errors are the hardest to find. The program compiles and runs without crashing, but produces wrong results. The compiler can't help you — you must trace through the logic yourself.
Off-by-One Error
1#include <stdio.h>23int main() {4 int sum = 0;5 6 // Goal: Sum numbers 1 to 5 (should be 15)7 for (int i = 1; i < 5; i++) { // Should be i <= 58 sum += i;9 }10 11 printf("Sum of 1-5: %d\n", sum); // Prints 10, not 15!12 13 return 0;14}Expected: Sum of 1-5: 15
Using = Instead of ==
1#include <stdio.h>23int main() {4 int x = 5;5 6 // BUG: This ASSIGNS 10 to x, doesn't compare!7 if (x = 10) { // Should be x == 108 printf("x is 10\n"); // This always prints!9 }10 11 printf("x is now: %d\n", x); // x is now 10!12 13 return 0;14}x is now: 10
Bug: x was changed from 5 to 10!
Debugging Tips for Logical Errors
- 1.Add
printf()statements to trace variable values - 2.Use a debugger (gdb) to step through code line by line
- 3.Test with simple, known inputs first
- 4.Check boundary conditions (first, last, empty, max)
- 5.Read your code out loud — sometimes you'll catch the bug
6. Unreachable Code Error
Unreachable code is code that will never execute due to the control flow. The compiler detects this and issues a warning or error.
Common Causes:
Code After Return Statement
1#include <stdio.h>23int main() {4 printf("Hello!\n");5 6 return 0; // Function exits here!7 8 // UNREACHABLE - Never executed!9 printf("Goodbye!\n");10}Code After Break Statement
1#include <stdio.h>23int main() {4 int value = 2;5 6 for (;;) { // Infinite loop7 if (value == 2) {8 break; // Exit loop immediately!9 10 // UNREACHABLE - Never executed!11 printf("This never prints\n");12 }13 }14 15 return 0;16}Code After Continue Statement
1#include <stdio.h>23int main() {4 for (int i = 0; i < 5; i++) {5 continue; // Jump to next iteration!6 7 // UNREACHABLE - Never executed!8 printf("Iteration %d\n", i);9 }10 11 printf("Loop complete\n");12 return 0;13}Always-False Conditions
1#include <stdio.h>2#include <math.h>34int main() {5 // sqrt(2) is about 1.414, never greater than 56 double x = sqrt(2);7 8 if (x > 5) { // 1.414 > 5 is ALWAYS false!9 // UNREACHABLE10 x++;11 }12 13 // 2 + 1 = 3, never equals 414 int n = 2 + 1;15 16 if (n == 4) { // 3 == 4 is ALWAYS false!17 // UNREACHABLE18 printf("Equal\n");19 }20 21 return 0;22}!Code Pitfalls: Common Mistakes & What to Watch For
Copied code can categorize and explain error types but often fails to teach the proactive mindset needed to prevent them in the first place.
If you search online "what are the types of errors in C?", it will give you a textbook answer: syntax, semantic, runtime, logical, linker errors. However, it rarely emphasizes that the *order* of detection matters hugely for debugging effort (compile-time is cheap, runtime is expensive) or that defensive programming habits can prevent most runtime and logical errors before they occur.
The Trap: Online sources provide reactive information—what errors *are*—rather than proactive strategies—how to *avoid* them. They might not emphasize the importance of compiler warnings (`-Wall -Wextra`), static analyzers, or coding conventions that prevent common mistakes. Learning about errors without learning prevention is like studying diseases without studying hygiene.
The Reality: The best programmers aren't those who can fix all errors; they're those who write code that rarely has errors. Use resources to understand error types, but develop habits that prevent them: enable all compiler warnings, initialize all variables, check all return values, and use static analysis tools regularly.
Frequently Asked Questions
Q:What's the easiest type of error to fix?
A: Syntax errors! The compiler tells you exactly what's wrong and on which line. Read the error message, fix the typo or missing semicolon, and recompile.
Q:Why do I get "undefined reference" errors?
A: Linker can't find the function definition. Either you forgot to link a library (-lm for math), misspelled a function name, or didn't include the source file in compilation.
Q:How do I find logical errors?
A: These are hardest because the program runs fine but gives wrong results. Use a debugger to step through code, add printf statements to trace values, and test with known inputs.
Q:Should I treat warnings as errors?
A: Yes! Use -Werror to make warnings fail compilation. Most warnings indicate real bugs — fix them before they become runtime errors.
Summary: Error Detection Checklist
Compile-Time Errors
- Check for missing semicolons
- Declare variables before use
- Match all brackets
- Include required headers
Linker Errors
- Define all declared functions
- Link required libraries (-lm)
- Check for typos in function names
- Include all source files in build
Runtime Errors
- Check divisor is not 0 before dividing
- Validate array indices
- Check malloc return value
- Initialize pointers before use
Logical Errors
- Use == for comparison, not =
- Check loop boundaries (off-by-one)
- Verify operator precedence
- Test with edge cases
Best Practices to Minimize Errors
- 1.Compile with
-Wall -Wextraflags - 2.Fix warnings — they often indicate bugs
- 3.Test incrementally as you write code
- 4.Use a debugger (gdb) for runtime issues
- 5.Initialize all variables
- 6.Always check return values
Test Your Knowledge
Related Tutorials
Basic Syntax in C
Learn the fundamental building blocks of C programs. Understand the main() function, how to write comments, and why proper formatting makes code readable.
Common Beginner Mistakes in C
Avoid the pitfalls every C beginner faces! Learn about the most common mistakes: = vs ==, integer division, array bounds, uninitialized variables, string issues, and pointer problems.
Enumerations in C
Create named constants for better code readability. Instead of using 0, 1, 2 for days, use MON, TUE, WED with enums.
Have Feedback?
Found something missing or have ideas to improve this tutorial? Let us know on GitHub!