Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid "null argument where non-null required" compiler warning

Compiling the following code:

#include <string.h>
#define FOO (NULL)

int main(int argc, char *argv[])
{
    char *foo;

    if (FOO)
        foo = strdup(FOO);

    return 0;
}

results in the following compiler warning:

foo.c: In function ‘main’:
foo.c:9:3: warning: null argument where non-null required (argument 1) [-Wnonnull]
   foo = strdup(FOO);
   ^

However, strdup won't be called if FOO is NULL because of the if (FOO) check. Is there any way to avoid this warning?

Thanks!

like image 750
profzoom Avatar asked Oct 22 '14 12:10

profzoom


2 Answers

You are correct that you have protected invocation of strdup with a clause to ensure that strdup is never called with a NULL argument.

But the part of the compiler that emits the warning for the function invocation isn't the same part that knows that the invocation can never happen.

You might instead obscure the NULL with an expression that ensure that the generated argument expression can never be NULL.

e.g.

if (FOO) foo = strdup(FOO?FOO:"");

or

if (FOO) foo = strdup(FOO + !FOO);

Here is is "clear" (to the compiler at least) that strdup cannot be called with a NULL value, and your if clause makes sure that it is never called with what was is no longer a NULL value.

At this point we wave our hands and say that the compiler will optimise it all away, and to help us visually optimise it all away, we have:

#define NON_NULL(x) ((x)?(x):"")

and for debug builds, something like:

#define NON_NULL(x) ((x)?(x):(abort(),""))

We might makes use of the GNU extension ?: (with optional missing middle clause defaulting to the first clause) to avoid evaluating (x) more than once.

#define NON_NULL(x) ((x)?:"")

and for debug builds, something like:

#define NON_NULL(x) ((x)?:(abort(),"")

Now you can present something that is technically more obscure but apparently more meaningful:

if (FOO) foo = strdup(NON_NULL(FOO));

And pretend that NON_NULL is some formal notation and acknowledgement.

like image 93
Sam Liddicott Avatar answered Oct 07 '22 21:10

Sam Liddicott


If the idea is to assign a value to foo if FOO is defined, you could try:

//#define FOO "lorem ipsum"

int main()
{
    char *foo;
    #ifdef FOO
        foo = strdup(FOO);
    #endif
}

It also has an advantage that the entire if code is not included when not needed.

like image 35
AlexD Avatar answered Oct 07 '22 22:10

AlexD