Trying to declare identifier locally and hide a file scope identifier

Discussion in 'C Programming' started by Kobu, Feb 24, 2005.

  1. Kobu

    Kobu Guest

    The code below isn't compiling for me (error message: conflicting types
    for 'total' - pointing to the extern declaration).

    Why wouldn't this work, since the types are different, the extern
    declaration obviously refers to the 'long total' in total.c? Is my
    compiler wrong?



    total.c
    -------
    long total = 30;


    main.c
    -------

    #include <stdio.h>
    #include <stdlib.h>

    static int total = 20;

    int main(void)
    {
    long temp;
    extern long total;

    /* rest of main */

    temp = total;

    printf("%d\n", temp);

    system("PAUSE");
    return 0;
    }
     
    Kobu, Feb 24, 2005
    #1
    1. Advertising

  2. Kobu

    Kobu Guest

    Kobu wrote:
    > The code below isn't compiling for me (error message: conflicting

    types
    > for 'total' - pointing to the extern declaration).
    >
    > Why wouldn't this work, since the types are different, the extern
    > declaration obviously refers to the 'long total' in total.c? Is my
    > compiler wrong?
    >
    >
    >
    > total.c
    > -------
    > long total = 30;
    >
    >
    > main.c
    > -------
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > static int total = 20;
    >
    > int main(void)
    > {
    > long temp;
    > extern long total;
    >
    > /* rest of main */
    >
    > temp = total;
    >
    > printf("%d\n", temp);
    >
    > system("PAUSE");
    > return 0;
    > }



    I tried the program with main.c changed to the following, and it still
    didn't work (same error message):


    main.c - 2nd version
    ------

    #include <stdio.h>
    #include <stdlib.h>

    static int total = 20;

    int main(void)
    {
    int total;
    {
    long temp;
    extern long total;

    temp = total;
    printf("%d\n", temp);
    }
    return 0;
    }


    Shouldn't the 'int total' in main force the 'extern long total' to have
    external linkage?
     
    Kobu, Feb 24, 2005
    #2
    1. Advertising

  3. Kobu wrote:

    > The code below isn't compiling for me (error message: conflicting types
    > for 'total' - pointing to the extern declaration).


    You have an identifier with internal linkage at file scope, and then you
    "import" another identifier of the same name, which has external linkage
    and therefore cannot refer to the same object. As a result, the names
    collide.

    > Why wouldn't this work, since the types are different


    Since when does that matter? This is also not allowed:
    int a;
    double a;
    There is no overloading in C.

    > total.c
    > -------
    > long total = 30;
    >
    >
    > main.c
    > -------
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > static int total = 20;


    What I'm not completely sure about: Is it legal up to this point? Can you
    define an identifier with external linkage in one source file and one of
    the same name with internal linkage in another file, as long as you do not
    declare the former there also? My Linux system links it without a warning,
    but I'm not sure if it's being overly generous.


    Christian
     
    Christian Kandeler, Feb 24, 2005
    #3
  4. On Thu, 24 Feb 2005 10:08:21 +0100, Christian Kandeler
    <_invalid> wrote:

    >> total.c
    >> -------
    >> long total = 30;
    >>
    >>
    >> main.c
    >> -------
    >>
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >>
    >> static int total = 20;

    >
    > What I'm not completely sure about: Is it legal up to this point? Can you
    > define an identifier with external linkage in one source file and one of
    > the same name with internal linkage in another file, as long as you do not
    > declare the former there also? My Linux system links it without a warning,
    > but I'm not sure if it's being overly generous.


    Certainly it's legal, that's the point of having internal linkage, it's
    known only to that module. If I had to try to predict every identifier
    that some module somewhere in a large system might have defined as an
    external name it would be totally unworkable.

    (Of course, if C imported the "namespace" concept from C++ it would make
    writing libraries much simpler. But don't hold your breath for that...)

    Chris C
     
    Chris Croughton, Feb 24, 2005
    #4
  5. On Wed, 23 Feb 2005 21:43:34 -0800, Kobu wrote:

    > Kobu wrote:
    >> The code below isn't compiling for me (error message: conflicting

    > types
    >> for 'total' - pointing to the extern declaration).
    >>
    >> Why wouldn't this work, since the types are different, the extern
    >> declaration obviously refers to the 'long total' in total.c? Is my
    >> compiler wrong?


    Your compiler is correct.

    >> total.c
    >> -------
    >> long total = 30;
    >>
    >>
    >> main.c
    >> -------
    >>
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >>
    >> static int total = 20;
    >>
    >> int main(void)
    >> {
    >> long temp;
    >> extern long total;
    >>
    >> /* rest of main */
    >>
    >> temp = total;
    >>
    >> printf("%d\n", temp);
    >>
    >> system("PAUSE");
    >> return 0;
    >> }


    The standard says in 6.2.2.p4:

    "For an identifier declared with the storage-class specifier extern in a
    scope in which a prior declaration of that identifier is visible, if
    the prior declaration specifies internal or external linkage, the linkage
    of the identifier at the later declaration is the same as the linkage
    specified at the prior declaration. If no prior declaration is visible,
    or if the prior declaration specifies no linkage, then the identifier has
    external linkage."

    So both declarations of total in main.c have internal linkage, which means
    that 'extern long total' is linked to 'static int total = 20' in main.c
    and not 'long total = 20' in total.c. However the types are incompatible
    for that linking.

    > I tried the program with main.c changed to the following, and it still
    > didn't work (same error message):
    >
    >
    > main.c - 2nd version
    > ------
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > static int total = 20;
    >
    > int main(void)
    > {
    > int total;
    > {
    > long temp;
    > extern long total;
    >
    > temp = total;
    > printf("%d\n", temp);
    > }
    > return 0;
    > }
    > }
    > }
    > Shouldn't the 'int total' in main force the 'extern long total' to have
    > external linkage?


    Yes it should because 'int total' is now the prior declaration that is
    visible at 'extern long total', and it has no linkage. However the
    standard also says in 6.2.2p7:

    "If, within a translation unit, the same identifier appears with both internal and external
    linkage, the behavior is undefined."

    This situation occurs in your new code. However if I understand you
    correctly your compiler produces a misleading diagnostic.

    Lawrence
     
    Lawrence Kirby, Feb 24, 2005
    #5
  6. Kobu

    Kobu Guest

    Lawrence Kirby wrote:
    > On Wed, 23 Feb 2005 21:43:34 -0800, Kobu wrote:
    >
    > > Kobu wrote:
    > >> The code below isn't compiling for me (error message: conflicting

    > > types
    > >> for 'total' - pointing to the extern declaration).
    > >>
    > >> Why wouldn't this work, since the types are different, the extern
    > >> declaration obviously refers to the 'long total' in total.c? Is my
    > >> compiler wrong?

    >
    > Your compiler is correct.
    >


    [snipped my incorrect code example]

    > > }
    > > Shouldn't the 'int total' in main force the 'extern long total' to

    have
    > > external linkage?

    >
    > Yes it should because 'int total' is now the prior declaration that

    is
    > visible at 'extern long total', and it has no linkage. However the
    > standard also says in 6.2.2p7:
    >
    > "If, within a translation unit, the same identifier appears with both

    internal and external
    > linkage, the behavior is undefined."
    >
    > This situation occurs in your new code. However if I understand you
    > correctly your compiler produces a misleading diagnostic.
    >
    > Lawrence



    I have a question about internal linkage. I want to define a
    file-scope variable with internal linkage (ex: static int i; at top of
    translation unit) and then I want this to be shadowed by a different
    'i' within a large function. Then inside a nested block in the
    function, I want to refer to the file-scope 'i'.

    Something like this:

    static int i; /* file-scope, internal linkage */

    void foo()
    {
    int i; /* block scope, no linkage */

    /* some code here */
    {
    extern int i; /* block, internal linkage */

    /* some code here */
    }

    /* some code here */
    }

    /* rest of translation unit */



    Your post claims that this is how the C Standard treats deeply nested
    'extern' declarations, but my compiler is complaining. Your post:
    http://groups-beta.google.com/group..._doneTitle=Back to Search&&d#bca14942f7fabe80


    My compiler is complaining about internal and external declarations of
    same identifier (which tells me the deeply nested 'i' is defaulting to
    external linkage, instead of "grabbing" the linkage from the previous
    file scope declaration of 'i', like your old post explain -- which is
    always what I thought happened).

    The standard mentions this "grabbing affect," much like your post did,
    but it's defaulting to external. Can someone clear this up (possibly
    test this on their compiler, or point out my mistake).
     
    Kobu, Feb 24, 2005
    #6
  7. Kobu wrote:

    >
    > I have a question about internal linkage. I want to define a
    > file-scope variable with internal linkage (ex: static int i; at top

    of
    > translation unit) and then I want this to be shadowed by a different
    > 'i' within a large function. Then inside a nested block in the
    > function, I want to refer to the file-scope 'i'.
    >
    > Something like this:
    >
    > static int i; /* file-scope, internal linkage */
    >
    > void foo()
    > {
    > int i; /* block scope, no linkage */
    >
    > /* some code here */
    > {
    > extern int i; /* block, internal linkage */
    >
    > /* some code here */
    > }
    >
    > /* some code here */
    > }
    >
    > /* rest of translation unit */
    >
    >
    >
    > Your post claims that this is how the C Standard treats deeply nested
    > 'extern' declarations, but my compiler is complaining. Your post:
    >

    http://groups-beta.google.com/group..._doneTitle=Back to Search&&d#bca14942f7fabe80
    >
    >
    > My compiler is complaining about internal and external declarations

    of
    > same identifier (which tells me the deeply nested 'i' is defaulting

    to
    > external linkage, instead of "grabbing" the linkage from the previous
    > file scope declaration of 'i', like your old post explain -- which is
    > always what I thought happened).
    >
    > The standard mentions this "grabbing affect," much like your post

    did,
    > but it's defaulting to external. Can someone clear this up (possibly
    > test this on their compiler, or point out my mistake).


    Your compiler is right and Lawrence's explanation was
    a little off in his old post. extern will, as you say,
    "grab" the linkage of any visible declaration that
    doesn't have no lnkage. The static int i at file scope
    is not visible at the point where you declare the nested
    extern int i, so the only declaration for i it sees at
    that point is the no linkage declaration just inside the
    opening brace for void food(). This causes it to default
    to external linkage, which creates a conflict with the
    internal linkage of the file scope i. Your compiler is
    right.
     
    E. Robert Tisdale, Feb 24, 2005
    #7
  8. Kobu

    Kobu Guest

    E. Robert Tisdale wrote:
    > Kobu wrote:
    >
    > >
    > > I have a question about internal linkage. I want to define a
    > > file-scope variable with internal linkage (ex: static int i; at

    top

    Snipped a lot of stuff unrelated to my request below.

    > This causes it to default
    > to external linkage, which creates a conflict with the
    > internal linkage of the file scope i. Your compiler is
    > right.


    I prefer getting an answer from a non-troll.
     
    Kobu, Feb 25, 2005
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    1,785
  2. Replies:
    2
    Views:
    919
    Owen Jacobson
    Dec 11, 2007
  3. S_K
    Replies:
    0
    Views:
    667
  4. James H. Markowitz

    Scope of locally declared arrays

    James H. Markowitz, Oct 20, 2010, in forum: C Programming
    Replies:
    3
    Views:
    374
    Eric Sosman
    Oct 21, 2010
  5. msoulier

    trying to install gems locally

    msoulier, Jun 12, 2006, in forum: Ruby
    Replies:
    1
    Views:
    79
    msoulier
    Jun 12, 2006
Loading...

Share This Page