https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67386
--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> --- Thanks. I think I may have misinterpreted the C90 rules that describe implicit function declarations. The C90 text says: If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration extern int identifier(); appeared. My reading was that the implicit declaration is intended to be in effect only for the call to the otherwise undeclared function, but GCC and the other compilers I've tried let it persist (at least) until the end of the scope and use it for references to the undeclared function that aren't calls (such as assigning its address to a pointer). While trying to better understand both the rule and the implementation (since it affects the fix for pr66516), I created the following test case and tried it with GCC and the other compilers. GCC's output for the test case is below (the errors are the same with c98, gnu98, c99, gnu99, c11, and gnu11 as arguments to -std=, and with or without -pedantic). Clang, however, doesn't issue any errors, and neither does IBM xlc. The EDG front end behaves the same as GCC. I think Clang and IBM xlc are both wrong since the reference to abs on line 8 should clearly be diagnosed. The C90 words aren't completely clear about where in the innermost block the extern int identifier(); declaration is supposed to appear but it stands to reason that it should appear where all other declarations must appear in C90: before any executable code. So diagnosing the reference to abs on line 11 is incorrect because the call to abs(0) on the following line should introduce an implicit declaration of the function just before line 11 where its address is taken. Unless you disagree, I'll close this as NOTABUG and open a new bug for the incorrect diagnostic on line 11. $ cat -n t.c && ~/bin/gcc-5.1.0/bin/gcc -c t.c 1 int (*p)(int); 2 int i; 3 4 void f0 (void) { 5 i = abs (0); // okay, abs implicitly declared in this scope 6 } 7 void f1 (void) { 8 p = abs; // error, no implicitly declaration in scope 9 } 10 void f2 (void) { 11 p = abs; // GCC bug? 12 i = abs (0); // injects an implicit declaration into the enclosing block 13 } 14 void f3 (void) { 15 i = abs (0); // introduces an implicit declaration into scope 16 p = abs; // okay, abs implicitly declared above 17 } 18 t.c: In function ‘f0’: t.c:5:9: warning: implicit declaration of function ‘abs’ [-Wimplicit-function-declaration] i = abs (0); ^ t.c: In function ‘f1’: t.c:8:9: error: ‘abs’ undeclared (first use in this function) p = abs; ^ t.c:8:9: note: each undeclared identifier is reported only once for each function it appears in t.c: In function ‘f2’: t.c:11:9: error: ‘abs’ undeclared (first use in this function) p = abs; ^