Search code examples
cfunctiongccscopec99

Ambiguous behavior by GCC when it ought to decide scope for a function declaration


By reading the C99 standard specification draft (n1256) section 6.7.5.3 paragraph 17, from what I can take away the function declarations (including implicit) inside a block scope shall have a block scope. Simple and makes sense.

However it doesn't make any sense, because when I compile this code:

void func1 () {
    int f(int);
}
void func2 () {
    float f(float);
}
int main (void) {
    return 0;
}

the compiler yields an error:

error: conflicting types for ‘f’; have ‘float(float)’

as if it sees both declarations at file scope. Another similar scenario would be if I replace the function declarations with a function call without having a visible declaration for it first as to force an implicit declaration. (And yes, I am aware that this is an obsolete feature). What happens is that the implicit function declaration warning is issued only once, therefore urging me to believe that it was also somehow magically declared at file scope. The only sane explanation that I have is some GCC extension and I did find something like that, but it is documented in ARM developer. link

By the looks of it, it does cause the declarations to be visible at file scope (disregarding standard C?) but then why and how on earth it makes an exception for it when compiling with -Werror=shadow? It should prompt an error that it shadows a global declaration. Once and for all, how are those declarations actually handled by the compiler and linker and why?


Solution

  • The issue you have here is that the function declarations in question have block (function) scope, but also have external linkage, and it is that external linkage where the conflict occurs.

    Now from the spec, having linkage conflicts like this is not required to cause a diagnostic but does cause undefined behavior, so the compiler is not incorrect to flag this as an error.