Home:ALL Converter>conflicting types vs incompatible implicit declaration

conflicting types vs incompatible implicit declaration

Ask Time:2012-08-06T16:55:36         Author:junwanghe

Json Formatter

The related C program is below:

    #include <stdio.h>

    void testifbarisvisible();

    int main()
    {
            void bar(int);
        bar(1);
        testifbarisvisible();
    }

    void testifbarisvisible()
    {
        bar(2);
    }

    void bar(int x)
    {
        printf("functionbar\n");
    }

The output of gcc is:

% gcc -std=c99 -c /tmp/notfilescope.c
/tmp/notfilescope.c: In function ‘testifbarisvisible’:
/tmp/notfilescope.c:14:2: warning: implicit declaration of function ‘bar’
/tmp/notfilescope.c:7:7: note: previous declaration of ‘bar’ was here
/tmp/notfilescope.c:14:2: error: incompatible implicit declaration of function ‘bar’
/tmp/notfilescope.c:7:7: note: previous implicit declaration of ‘bar’ was here

After I removed the statement in line 7, the output is:

% gcc -std=c99 -c /tmp/notfilescope.c
/tmp/notfilescope.c: In function ‘main’:
/tmp/notfilescope.c:8:2: warning: implicit declaration of function ‘bar’
/tmp/notfilescope.c: At top level:
/tmp/notfilescope.c:17:6: warning: conflicting types for ‘bar’
/tmp/notfilescope.c:8:2: note: previous implicit declaration of ‘bar’ was here

The version of gcc is:

% gcc --version
gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE

I'm confused about the difference between the two outputs of gcc.

This is from the gcc's documents, "Declarations of external variables and functions within a block apply only to the block containing the declaration.In other words, they have the same scope as any other declaration in the same place."

So I think that the function declaration in line 7 has no relationship with the function call in line 14. But the result indicate that opinion was wrong. They are all implicit declaration of function 'bar', but one of them leads to error (incompatible implicit declaration of function ‘bar’), and the other one leads to warning (conflicting types for ‘bar’), why?

This question has confused me a long time. Can someone help me?

Author:junwanghe,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/11825172/conflicting-types-vs-incompatible-implicit-declaration
Eric Postpischil :

Within main, bar has only function scope; it is known only within main. However, C has another process called linkage. Per C 1999 6.2.2 1, “An identifier declared in different scopes or in the same scope more than once can be made to refer to the same object or function by a process called linkage.”\n\nIn main, the declaration void bar(int); declares bar with external linkage, per C 1999 6.2.2 5: “If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern.”\n\nThen, in testifbarisvisible, bar is not in scope. The statement bar(2); implicitly declares bar to be external, and, because bar is not in scope, it is an implicit declaration of bar with no prototype. This implicit declaration has a different type than the previous void bar(int);, but, because of linkage, it must refer to the same function. (Per 6.2.2 2, “In... an entire program, each declaration of a particular identifier with external linkage denotes the same object or function.”) This is a conflict, so the compiler produces an error.\n\nWhen you remove void bar(int);, there is no explicit declaration of bar in main. Instead, bar is implicitly declaration by the following line, bar(1);. This implicit has the same type as the implicit declaration in testifbarisvisible. Because the declarations are identical, there is no error. The compiler still gives you a warning because implicit declarations are dangerous (because the eventual explicit declaration might be in a different file and might be different, which can cause undiagnosed errors at execution).",
2012-08-06T10:02:03
HonkyTonk :

I'd say the result you get is reasonable.\n\nAs soon as you write\n\nvoid bar(int);\n\n\nyou are declaring that there is a function with that signature somewhere in this compilation unit and this is not an implicit declaration, it is explicit, if anything. But, as the documentation notes, this declaration does not escape the scope it is in, so when you get to\n\nvoid testifbarisvisible()\n{\n bar(2);\n}\n\n\nno such declaration is in scope, and the compiler complains.",
2012-08-06T09:17:58
yy