0% found this document useful (0 votes)
3 views4 pages

Error Handling Material

Error Handling in C Language outlines various techniques for managing runtime errors, as C lacks built-in exception handling. Key methods include using return codes, the errno variable with perror(), setjmp/longjmp for non-local jumps, and assert for debugging. Best practices emphasize consistent error codes, meaningful messages, logging errors, and resource cleanup.

Uploaded by

tvijaykumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views4 pages

Error Handling Material

Error Handling in C Language outlines various techniques for managing runtime errors, as C lacks built-in exception handling. Key methods include using return codes, the errno variable with perror(), setjmp/longjmp for non-local jumps, and assert for debugging. Best practices emphasize consistent error codes, meaningful messages, logging errors, and resource cleanup.

Uploaded by

tvijaykumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Error Handling in C Language

Error Handling in C Language focuses on managing errors during runtime, as C


doesn’t have built-in exception handling like other languages (e.g., C++ or Java).
Instead, error handling in C is usually achieved through mechanisms such as return
codes, errno, setjmp/longjmp, and assert.

Here’s a detailed breakdown of Error Handling techniques in C:

1. Return Codes

 Overview: Functions in C often return values to indicate success or failure.


Common practice is to return 0 for success and non-zero values for errors.

Example:

#include <stdio.h>

int divide(int numerator, int denominator) {


if (denominator == 0) {
return -1; // Error code for division by zero
}
return numerator / denominator;
}

int main() {
int result = divide(10, 0);
if (result == -1) {
printf("Error: Division by zero!\n");
} else {
printf("Result: %d\n", result);
}
return 0;
}

Best Practice: Define constants for error codes using #define.

2. errno and perror()

Overview: The global variable errno holds error codes set by system calls and
library functions (like malloc(), open(), etc.). perror() can be used to print the
corresponding error message based on errno.

Common errno Values:

o ENOMEM - Out of memory.


o EINVAL - Invalid argument.
o EBADF - Bad file descriptor.
o EIO - I/O error.

Example:

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

int main() {
FILE *file = fopen("nonexistent_file.txt", "r");
if (file == NULL) {
perror("Error opening file");
} else {
fclose(file);
}
return 0;
}

This will print something like:

Error opening file: No such file or directory

3. setjmp() and longjmp()

Overview: These functions allow non-local jumps, which can simulate


exception handling. setjmp() sets a point to return to, and longjmp() jumps to
that point, enabling error handling and resource cleanup.

Example

#include <stdio.h>
#include <setjmp.h>

jmp_buf buf;

void myFunction() {
printf("Inside function\n");
longjmp(buf, 1); // Jump back to setjmp
printf("This will not be printed.\n");
}

int main() {
if (setjmp(buf) != 0) {
printf("Error: An error occurred!\n");
} else {
myFunction(); // Call a function that causes an error
}
return 0;
}

The program will output:

Inside function
Error: An error occurred!

Note: longjmp() causes the program to jump back to the point of setjmp() and
can be used for error recovery.
4. assert() for Debugging

Overview: The assert() macro from the assert.h header checks whether an
expression is true. If it's false, the program prints an error message and abort

Example

#include <stdio.h>
#include <assert.h>

int divide(int a, int b) {


assert(b != 0); // Check for division by zero
return a / b;
}

int main() {
int result = divide(10, 0); // This will trigger an assertion failure
printf("Result: %d\n", result);
return 0;
}

This will print something like:

Assertion failed: b != 0, file program.c, line 7

Note: Assertions are typically disabled in production code (using -DNDEBUG


during compilation).

5. Error Handling in Library Functions

Many library functions return error codes. For example, the malloc() function
returns NULL when memory allocation fails. Checking for NULL after using
malloc() is important.

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
int *arr = (int *)malloc(10 * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Use arr
free(arr);
return 0;
}

6. Custom Error Handling Functions

You can define your own error handling mechanism. For example, creating a
function that logs errors to a file.

Example:
#include <stdio.h>

void log_error(const char *message) {


FILE *logFile = fopen("error.log", "a");
if (logFile != NULL) {
fprintf(logFile, "Error: %s\n", message);
fclose(logFile);
} else {
printf("Error logging failed!\n");
}
}

int main() {
log_error("File not found.");
return 0;
}

7. Using exit() for Unrecoverable Errors

When an error occurs that prevents the program from continuing, you can use
exit() to terminate the program. You can pass a status code to indicate success
or failure (0 for success, non-zero for failure).

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
printf("Fatal error occurred, exiting...\n");
exit(1); // Exit the program with an error code
}

Best Practices for Error Handling

 Return codes: Use consistent error codes across your program.


 Error messages: Provide meaningful error messages, especially when using
perror().
 Error logs: Log errors to files or external systems, especially for critical
systems.
 Clean up resources: Always clean up allocated resources (memory, file
handles, etc.) before exiting, even on errors.

Signature of the Faculty HoD

You might also like