http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57475
Bug ID: 57475 Summary: "incompatible pointer type" message is not helpful enough Product: gcc Version: 4.7.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: ebb9 at byu dot net gcc 4.5.3 (as shipped on cygwin) gave a rather unhelpful message for a root cause bug in cygwin's <sys/un.h>: http://cygwin.com/ml/cygwin/2013-05/msg00451.html $ cat foo.c #ifdef WORKAROUND # include <sys/socket.h> #endif #include <sys/un.h> #include <sys/socket.h> int main(void) { const struct msghdr msg; return sendmsg(0, &msg, 0); } $ gcc -o foo -Wall foo.c foo.c: In function 'main': foo.c:9:5: warning: passing argument 2 of 'sendmsg' from incompatible pointer type /usr/include/sys/socket.h:42:11: note: expected 'const struct msghdr *' but argument is of type 'const struct msghdr *' $ gcc -o foo -Wall foo.c -DWORKAROUND $ Huh? How can 'const struct msghdr *' not be compatible with itself? [It took me a while to finally understand: the bug in cygwin's <sys/un.h> causes the declaration of sendmsg() to declare a local 'struct msghdr' rather than using the global type] I checked other bugs that mention this message, but none of them apply (bug 37866, 14188, 30949). I've further reduced it down to this two-file example, as tested with gcc 4.7.2: $ cat foo.h #ifdef SILENT # pragma GCC system_header #endif extern int bar(struct foo *); struct foo { int i; }; $ cat foo.c #include "foo.h" int main(void) { struct foo f; return bar(&f); } $ gcc -c -o foo.o -Wall foo.c -DSILENT foo.c: In function ‘main’: foo.c:4:3: warning: passing argument 1 of ‘bar’ from incompatible pointer type [enabled by default] In file included from foo.c:1:0: foo.h:4:12: note: expected ‘struct foo *’ but argument is of type ‘struct foo *’ which mirrors the fact that Cygwin's <sys/un.h> is compiled as a system header, and therefore misses the more obvious real root cause: $ gcc -c -o foo.o -Wall foo.c In file included from foo.c:1:0: foo.h:4:23: warning: ‘struct foo’ declared inside parameter list [enabled by default] foo.h:4:23: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] foo.c: In function ‘main’: foo.c:4:3: warning: passing argument 1 of ‘bar’ from incompatible pointer type [enabled by default] In file included from foo.c:1:0: foo.h:4:12: note: expected ‘struct foo *’ but argument is of type ‘struct foo *’ I think it would be useful if the incompatible pointer type error message would ALSO call out a note on where the two types are first declared (if they are not built-in types), so that cases like mine, where the earlier error message about a parameter-list-local declaration was squelched is not quite so confusing.