I am currently working in an embedded environment with absolutely nothing (there's a boot loader and that's it). In this case, dereferencing NULL just crashes the entire box and does not provide any information with regards to where it occurred. There are no debugging utilities.
What I do have written so far is a basic kernel, context switching as well as both interrupt-drive and busy-wait IO to a UART that allows me to print information to a terminal with our version of printf. With this, we have a function that switches into the kernel and prints something like the following through the terminal:
Panic("\033[31mPanic: at line %d of file %s (function <%s>): \033[0m\r\n\r\n", \__LINE__, \__FILE__, \__FUNCTION__.);
What I'm wondering is if there is a way to wrap a null check with this invocation as a macro. Something like:
#define SAFE_DEREF(x) (x != NULL ? *x : Panic(...))
but that doesn't work as a lvalue.
Obviously, I can do a manual NULL check + panic for each variable but that is a large refactor and it would increase the amount of code by a good amount.
Is this even possible to do?
Thanks!
EDIT: Here's the final code:
#define d(x) ( *(((x) ? 0 : (Panic(ASSERT_MSG, __LINE__, __FILE__, __FUNCTION__, "NULL DEREF"),0)), x) )
Here is one way:
#define SAFE_DEREF(x) ((x) ? *(x) : (Panic(),*(x)))
but actually that's not great because you couldn't use it as an l-value. So, try this instead:
#define SAFE_DEREF(x) (*((x) ? (x) : (Panic(),(x)))
This still has the usual problem with macros that if (x) is an expression with side-effects, you end up performing the side-effects twice, so you have to be very careful.
q = SAFE_DEREF(p++); // OOPS!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With