I've found Zed Shaw's debug macros on his website when his C book "Learn C the Hard Way" was free to read. It was designed for Linux initially, and it works pretty well, been using it for a while.
Now, I've started to write C code for Windows and I'm using Visual Studio. I want to use these debug macros in a project I'm working on.
The problem is as follows: Let's say I want to use the check macro to make sure a function returned without error.
display = al_create_display(640, 480);
check(display, "Failed to create display");
The definition for the macros that will be used are the following:
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
However, the problem I encountered was that Visual Studio marks strerror()
as deprecated and aborts compilation. I plan on using threads in the project, so I don't want to go the "ignore" route, if possible.
What I did was I created a clean_errno()
function that does the same thing as the macro, but uses a global buffer variable and calls strerror_s()
to copy into it, then return a pointer to the log_err()
macro.
However now I have to:
Is there any other trick/hack that I don't know of that would provide an elegant and simple solution to this?
Strerror is deprecated because it's not thread safe. If you don't care about this fact then you can probably find some option in VS to turn off this warning.
But it would be equally simple to implement a thread-safe version using sterror_s(). Remember, your macros can do more than just evaluate expressions, specifically it's completely possible to allocate a buffer in the macro:
#define check(A, M, ...) \
if(!(A)) { \
char _buffer[128]; \
strerror_s(_buffer, 128, errno); \
fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " (M) "\n", __FILE__, \
__LINE__, errno? _buffer : "None", ##__VA_ARGS__); \
errno = 0; \
goto error; \
}
I haven't tested this code so it may have some bugs, but it should be a start.