http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58488
Bug ID: 58488 Summary: -Wuninitialized is useless for a variable whose address is later taken Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: eblake at redhat dot com Here's a simple example of where -Wuninitialized is rather useless at default optimization: $ cat foo.c #include <stdlib.h> int main(void) { char *oops; free(oops); void *other = #ifdef RELIABLE NULL #else &oops #endif ; return !other; } $ gcc -Werror -Wall -Wuninitialized -o foo -c foo.c $ gcc -Werror -Wall -Wuninitialized -o foo -c foo.c -DRELIABLE foo.c: In function ‘main’: foo.c:5:9: error: ‘oops’ is used uninitialized in this function [-Werror=uninitialized] free(oops); ^ cc1: all warnings being treated as errors $ gcc -Werror -Wall -Wuninitialized -o foo -c foo.c -O2 foo.c: In function ‘main’: foo.c:5:9: error: ‘oops’ is used uninitialized in this function [-Werror=uninitialized] free(oops); ^ cc1: all warnings being treated as errors $ gcc -Werror -Wall -Wuninitialized -o foo -c foo.c -DRELIABLE -O2 foo.c: In function ‘main’: foo.c:5:9: error: ‘oops’ is used uninitialized in this function [-Werror=uninitialized] free(oops); ^ cc1: all warnings being treated as errors I understand that -O2 enables better uninitialization checks, but I find it quite awkward that even without -O2, the mere taking an address of a variable hides it from the uninit checker. My end goal is to have a macro that does a one-shot evaluation of its argument: #define FREE(x) { typeof(x) *_x = &(x); free(*_x); *_x = NULL; } for safety, but that macro kills -Wuninit checking by virtue of the fact that it takes the address of the pointer. Even if I limit myself to a macro that evaluates its argument more than once (and forcing me to audit code to avoid FREE(side-effects) - if only there were a way to make the compiler automatically barf if it encounters side effects in a macro argument), I am unable to come up with a way to get the uninit checking that gcc provides regardless of optimization without also having the safety of ensuring the pointer isn't abused after the fact.