How to workaround the GCC warning, "the address of XXX will never be NULL"?
I'm working on a C program. There is a function which takes two pointer arguments, call it cmp()
. I present here a simplified stand-in for cmp()
for illustrative reasons:
int cmp(struct foo *a, struct foo *b)
{
return a->bar == b->bar;
}
I'd like to make a NULL-check macro, like this:
#define SAFE_CMP(a,b) (((a) != NULL && (b) != NULL) ? cmp((a),(b)) : 0)
I think this is perfectly fine. However, in when compiling with both -Wall
and a compliation switch that regards a warning as an error, the following code is troublesome:
int baz(struct foo *a)
{
struct foo b;
/* ... */
return SAFE_CMP(a, &b);
}
since gcc warns tha开发者_运维问答t "the address of b will never be NULL".
Is there any way to workaround this situation?
Having various helper macro like SAFE_CMP_1(safe_arg,unsafe_arg)
and SAFE_CMP_2(unsafe_arg,safe_arg)
etc. is the last thing I want. I'd like to have one helper macro applicable to all situations.
This seems to suppress the warning for me:
#define SAFE_CMP(a,b) (((void *)(a) != NULL && (void *)(b) != NULL) ? cmp((a),(b)) : 0)
...but personally, I would just create safe_cmp()
as a function itself.
int safe_cmp(struct foo *a, struct foo *b) {
return (a && b) ? (a->bar == b->bar) : 0;
}
"I'd like to have one helper macro appricable to all situation."
Why? One size does not fit all. GCC is doing you a favor by telling you a comparison will always have a certain result. The address of a stack variable will never be NULL. I would just write out the check in baz:
int baz(struct foo *a) {
struct foo b;
...
return a == NULL ? 0 : cmp(a, &b);
}
You could also do it in cmp
. It depends how you define the pre and post-conditions.
Another possible issue with your macro (not applicable for baz) is that a
and b
will be evaluated multiple times. Beware of:
SAFE_CMP(p++, p1++);
The gcc option -Wno-address
seems to remove the warnings.
When you have such warning consider possibility you have double && && mistake in your if () expression
精彩评论