Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No warning when returning NULL with gcc

Using gcc 5.2.0, I noticed that this code does not generate a warning:

#include <stddef.h>

int function(void)
{
    return NULL;
}

void procedure(void)
{
    return NULL;
}

I used the flags -Wall -Wextra -std=c99 -pedantic and I am running archlinux. I am not sure why this code works fine on gcc, especially since clang 3.7.0 does generate a warning.

I also tried with older versions of gcc like 4.9 or 4.7 and they both generate warnings.

The warnings are:

warning: return makes integer from pointer without a cast

and

warning: ‘return’ with a value, in function returning void

I should mention that I tried compiling gcc 5.2 on Debian and the result is the same. So archlinux does not seem to be the problem.

What is the rationale? I cannot seem to find anything related to this anywhere else.

Thank you!

like image 442
damwdan Avatar asked Sep 23 '15 06:09

damwdan


People also ask

How do I enable warnings in GCC?

GCC 4.3+ now has -Q --help=warnings , and you can even specify --help=warnings,C to just print out the C related warnings.

How do I turn off GCC warning?

If the value of y is always 1, 2 or 3, then x is always initialized, but GCC doesn't know this. To suppress the warning, you need to provide a default case with assert(0) or similar code. This option also warns when a non-volatile automatic variable might be changed by a call to longjmp.

How does GCC treat warning errors?

The warning is emitted only with --coverage enabled. By default, this warning is enabled and is treated as an error. -Wno-coverage-invalid-line-number can be used to disable the warning or -Wno-error=coverage-invalid-line-number can be used to disable the error.

How do I disable warning treatment as error?

You can make all warnings being treated as such using -Wno-error. You can make specific warnings being treated as such by using -Wno-error=<warning name> where <warning name> is the name of the warning you don't want treated as an error. If you want to entirely disable all warnings, use -w (not recommended).


1 Answers

This appears to be a regression in gcc 5.2.0 -- and, as far as I can tell, a weird one.

With gcc 4.4.5 and 4.8.4, the program (after adding the required #include <stddef.h>) produces warnings on both return NULL; statements, even without any extra command-line options.

With gcc 5.2.0, no warning is produced, even with gcc -c -Wall -Wextra -std=c99 -pedantic. For the second one, which returns a value from a void function, a diagnostic is mandatory.

Now here's the weird part.

$ gcc --version | head -n 1
gcc (GCC) 5.2.0
$ cat c.c
#include <stddef.h>

int function(void) {
#ifdef USE_NULL
   return NULL;
#else
    return ((void*)0);
#endif
}

void procedure(void) {
#ifdef USE_NULL
   return NULL;
#else
    return ((void*)0);
#endif
}
$ gcc -c c.c
c.c: In function ‘function’:
c.c:7:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
     return ((void*)0);
            ^
c.c: In function ‘procedure’:
c.c:15:12: warning: ‘return’ with a value, in function returning void
     return ((void*)0);
            ^
$ gcc -c -DUSE_NULL c.c
$ 

When USE_NULL is defined, no warnings are produced. Compiling with gcc -E -DUSE_NULL (which prints the preprocessor's output to stdout) confirms that NULL is defined as ((void*)0). But when I replace NULL with ((void*)0), the warnings are produced (as they should be).

I don't know what's going on. Once the macro NULL has been expanded, it should be indistinguishable from ((void*)0), and yet the compiler's behavior changes depending on which is used.

like image 55
Keith Thompson Avatar answered Oct 06 '22 20:10

Keith Thompson