Note
libcerr is a lightweight C library that extends standard error handling capabilities by providing a simple try-catch-like exception mechanism and enhanced logging utilities.
- 🎯 Exception Handling: A
try-catch-like system for C usingTRY,CATCH, andTHROWmacros.- 📣 Rich Logging: Colorful, leveled logging macros (
LOG_INFO,LOG_WARN,LOG_ERR, etc.).- 🚧 Assertions: An
ASSERTmacro with enhanced logging for better debugging.- 🔩 Thread-Local: Designed with thread safety in mind using thread-local storage for error contexts.
- 🗂️ Memory Cache: Automatic memory allocation tracking with
MALLOC(),CALLOC(),REALLOC(),FREE()macros.- 🛠️ Customizable: Easily configurable via macros.
#define CERR_IMPLEMENTATION // Only define this ONCE in your entire project
#include <libcerr.h>
// Define your own exceptions
#define MY_EXCEPTION 10
void might_fail() {
THROW_MSG(MY_EXCEPTION, "Function failed !");
}
int main() {
TRY {
might_fail();
} CATCH(MY_EXCEPTION) {
LOG_ERR("Caught: %s", CERR_WHY());
}
might_fail(); // this will abort
}The logging macros provide colorful, formatted output to
stderrby default. Use LOG_LEVEL to filter output: 0 is nothing, 1 is OK/ERR, 2 adds WARN, 3 adds INFO and 4 adds DEBUG.
#define LOG_FDOUT stdout
#define LOG_LEVEL 3
#include <libcerr.h>
int main() {
int x = 5;
LOG_INFO("Starting application with x = %d...", x);
LOG_DEBUG("This is a debug message. "); // Log level 3, will not print
LOG_WARN("This is a warning message.");
LOG_ERR("This is a fatal error message.");
LOG_OK("Application finished.");
}Assertions will exit the program when the condition is not met even if protected by a TRY block.
int x = 5;
TRY {
ASSERT(x == 10, "This will fail and not be caught !")
} CATCH_ALL_LOG() {}The library provides memory allocation macros that automatically track all allocations. When the program exits, any unfreed memory is automatically cleaned up and a warning is logged about potential memory leaks. The cache system uses a fixed-size hash table (default
CERR_CACHE_SIZE= 65536 entries) for O(1) average insertion and removal. You can customize this by definingCERR_CACHE_SIZEbefore including the header (must be a power of 2).
#define CERR_IMPLEMENTATION
#include <libcerr.h>
int main() {
char *str = MALLOC(100); // Tracked allocation
char *arr = CALLOC(10, sizeof(int));
str = REALLOC(str, 200); // Tracked reallocation
FREE(str); // Safe free with double-free prevention
FREE(arr);
// Any unfreed memory is automatically cleaned up on exit
}Important
These macros must be defined before including <libcerr.h>.
| Macro | Description | Where to Define |
|---|---|---|
CERR_IMPLEMENTATION |
Instantiates global variables and cleanup functions required by the library. | Define in exactly one source file, preferably your entry point (e.g., main.c). |
CERR_NCACHE |
Disables the automatic memory caching system. MALLOC(), CALLOC(), REALLOC(), and FREE() become direct wrappers to standard library functions. |
Define in all source files that include <libcerr.h> if you want to disable caching. |
CERR_CACHE_SIZE |
Sets the maximum number of tracked allocations (default: 0x10000 = 65536). Must be a power of 2. |
Define before including the header if you need a different limit. |
LOG_LEVEL |
Sets the logging verbosity (0-4). | Define before including the header. |
LOG_FDOUT |
Sets the output file descriptor for logging (default: stderr). |
Define before including the header. |
main.c (entry point):
#define CERR_IMPLEMENTATION // Only define this ONCE in your entire project
#include <libcerr.h>
int main() {
void *ptr = some_function();
FREE(ptr);
}other_file.c (other source files):
#include <libcerr.h> // No CERR_IMPLEMENTATION here
void *some_function() {
return MALLOC(256);
}If you want to use standard malloc/free without tracking, define CERR_NCACHE at compile time:
gcc -DCERR_NCACHE -I./headers main.c other_file.c -o myprogramImportant
The project is still in its early stages and, for now, everything fits in the header, so no linking is necessary. (GCC or Clang remains mandatory for compilation)
- C Compiler
GCCorClangGNU Make
# Clone the repository
git clone https://github.com/MykleR/libcerr.git
cd libcerr
# Build it as a static/shared library (Link as you wish and include libcerr.h)
make
