Types of Errors in C: 100% Clarity with Examples & Fixes

Writing code in C is like giving a very strict teacher a set of instructions—every mistake gets noticed. That’s why understanding types of errors in C programming is essential. Errors are not just annoying—they stop your program from running as expected or at all.

In C, errors can occur at various stages: while writing the code (syntax), during program execution (runtime), or even when your logic is incorrect (logical errors). Each of these error types can crash your program or give wrong results.

This blog will walk you through all the main types of errors in C with clear examples and easy explanations, so beginners can not only understand them but also learn how to avoid them while coding.

What Are Errors in C Programming?

In C, an error is any issue in the code that prevents the program from compiling, linking, or executing correctly. Errors can be as simple as a missing semicolon or as complex as a misused pointer that crashes the program.

The compiler catches most of the syntax and semantic errors before the program is even run. Once compiled, runtime errors may still occur if something goes wrong during execution, like dividing a number by zero.

There are also logical errors, which aren’t caught by the compiler or runtime system but still lead to incorrect output. That’s why it’s important to understand where errors can pop up and how to handle them.

Syntax Errors

Definition

Syntax errors occur when the code does not follow the rules of the C language. These errors are detected during compilation and must be fixed before the program can run.

Examples

#include <stdio.h>
int main() {
    printf("Hello, World!"  // Missing closing parenthesis and semicolon
    return 0
}

This code will throw syntax errors due to the missing closing ) and ; after the printf() line.

Common Causes

  • Missing semicolons (;)
  • Mismatched or missing brackets {}, (), []
  • Using undeclared variables
  • Misspelled keywords (e.g., pritnf instead of printf)

How to Fix Them

  • Always check the compiler error messages; they usually point to the line and type of error.
  • Use an IDE or code editor that highlights syntax errors in real-time.
  • Read the code carefully to ensure all language rules are followed.

1. Semantic Errors

Definition and Difference from Syntax Errors

Semantic errors occur when the syntax of the code is correct, but the meaning or usage of code elements is incorrect. Unlike syntax errors, semantic errors are not about breaking language rules—they happen when code is grammatically correct but logically wrong from the compiler’s or system’s perspective.

While syntax errors are detected by the compiler as structural issues, semantic errors relate to how valid code is interpreted and whether it makes sense in the context of the program.

Example

#include <stdio.h>
int main() {
    int result;
    result = value + 10;  // 'value' is used before declaration
    return 0;
}

In this case, the compiler will throw a semantic error because value is not declared before it’s used.

Another example:

float add(int a, int b) {
    return a + b;
}

int main() {
    int sum = add(5, 3);  // Trying to assign a float to an int
    return 0;
}

Here, there’s a semantic mismatch in the return type and the receiving variable.

Fixing Approach

  • Ensure that all variables and functions are declared before use.
  • Pay attention to data types and return values.
  • Use compiler warnings (like -Wall in GCC) to catch subtle semantic issues.
  • Adopt consistent naming and type-checking practices.

2. Logical Errors

What Are Logical Errors?

Logical errors are the trickiest kind. Your code compiles and runs without crashing, but it doesn’t give the correct result. These errors occur when the logic or algorithm used to solve a problem is flawed.

Since the compiler can’t detect these, it’s up to the programmer to find them by manually testing and debugging.

Example

#include <stdio.h>
int main() {
    int a = 5, b = 10;
    if (a > b) {
        printf("A is greater\n");
    } else {
        printf("B is greater\n");
    }
    return 0;
}

This logic works, but what if the programmer mistakenly wrote:

if (a < b) {
    printf("A is greater\n");  // Incorrect message
}

The output is incorrect even though the program runs perfectly.

Tips to Debug and Avoid

  • Use print statements or a debugger to track variable values during execution.
  • Break down your logic into smaller chunks to test individually.
  • Write unit tests to check if functions give expected outputs.
  • Perform code reviews or explain your code logic to someone else (“rubber duck debugging”).

3. Runtime Errors

Definition and How They Occur

Runtime errors are errors that occur while the program is running, after successful compilation. These errors usually happen due to unexpected conditions during execution, such as invalid inputs, missing files, or operations that aren’t logically permitted (like dividing by zero).

Unlike syntax or semantic errors, runtime errors aren’t caught at compile time—they only show up when the program is actually run.

Examples

  • Division by zero: int a = 10, b = 0; int result = a / b; // Runtime error: division by zero
  • File not found: FILE *file = fopen("data.txt", "r"); if (file == NULL) { perror("Error opening file"); }
  • Accessing invalid memory: int *ptr = NULL; *ptr = 100; // Runtime error: segmentation fault

Error Handling in C

C offers basic tools to detect and respond to runtime errors:

  • errno: A global variable that stores the error code when a library function fails.
  • perror(): Prints a descriptive error message based on the current value of errno.
  • strerror(errno): Returns a string describing the error.

Example:

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {
    FILE *file = fopen("missing.txt", "r");
    if (file == NULL) {
        perror("File Error");
        printf("Error code: %d\n", errno);
        printf("Error message: %s\n", strerror(errno));
    }
    return 0;
}

4. Linker Errors

What Linker Errors Mean

Linker errors occur after compilation, during the linking phase. When you compile a program, each source file is compiled into an object file. The linker then combines these object files into a single executable.

If any references to functions or variables can’t be resolved during this phase, a linker error is thrown.

Common Causes

  • Undefined references: Calling a function that isn’t defined or not linked correctly. // main.c void hello(); // Declared but not defined int main() { hello(); // Linker error: undefined reference to `hello` return 0; }
  • Multiple definitions: Defining the same function or global variable in more than one file.
  • Mismatched declarations: Function declared in one way and defined in another.

How to Resolve Them

  • Make sure all functions are defined and not just declared.
  • Avoid duplicate definitions across multiple files.
  • Use extern for variables or functions that are defined in other files.
  • Use proper header file inclusion strategies and avoid circular dependencies.

Example Fix: Ensure the function is properly defined or linked:

// hello.c
#include <stdio.h>
void hello() {
    printf("Hello from another file!\n");
}

And compile using:

gcc main.c hello.c -o program

Compilation Errors vs Runtime Errors: Key Differences

Understanding the difference between compilation and runtime errors is essential for every C programmer. Here’s a quick comparison:

FeatureCompilation ErrorsRuntime Errors
When They OccurDuring the compilation phaseWhile the program is executing
ExamplesSyntax errors, semantic errorsDivision by zero, file not found, null pointers
DetectionDetected by the compilerDetected only when the program is run
ImpactPrevents the program from compilingProgram compiles but may crash or misbehave
Fixing MethodFix the code based on compiler messagesUse debugging tools and error handling

How to Debug Errors in C Efficiently

Debugging is an essential skill for writing clean and functional code. Here are some tools and best practices to help you debug errors effectively:

Tools for Debugging in C

  • GCC (GNU Compiler Collection): Use -Wall to enable all warnings. gcc -Wall program.c -o program
  • GDB (GNU Debugger): A powerful tool to run code step-by-step and inspect variables. gdb ./program

Good Practices

  • Use meaningful variable names and consistent formatting.
  • Always initialize variables before use.
  • Keep your code modular with small functions for better readability and debugging.
  • Regularly test your code with different inputs, especially edge cases.
  • Read compiler warnings and errors carefully—they’re often more helpful than they appear.

Tips for Beginners

  • Don’t ignore warnings; they often highlight potential bugs.
  • Use print statements to trace program flow.
  • Start small and build gradually—test each part before moving on.

Conclusion

Understanding the types of errors in C—syntax, semantic, logical, runtime, and linker—is the first step to becoming a confident C programmer. With practice, debugging tools, and careful coding habits, beginners can avoid common mistakes and write clean, error-free programs. Explore more C tutorials at Newtum and level up your programming journey!

About The Author

Leave a Reply