Thread: Linkage question

  1. #1
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99

    Linkage question

    I'm a bit puzzled by the following from chapter 3.5 of the C++ standard:

    "The name of a function declared in block scope, and the name of an object declared by a block scope extern declaration,
    have linkage. If there is a visible declaration of an entity with linkage having the same name and type, ignoring entities
    declared outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and
    receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed.
    Otherwise, if no matching entity is found, the block scope entity receives external linkage.[ Example:
    Code:
    static void f();
    static int i = 0; // 1
    void g() {
    extern void f(); // internal linkage
    int i; // 2: i has no linkage
    {
    extern void f(); // internal linkage
    extern int i; // 3: external linkage
    }
    }
    There are three objects named i in this program. The object with internal linkage introduced by the declaration in
    global scope (line //1 ), the object with automatic storage duration and no linkage introduced by the declaration on line
    //2, and the object with static storage duration and external linkage introduced by the declaration on line //3. —end
    example ]"

    On the basis of the above explanation, I would have expected the object declared in line //3 to be the same one that is defined in line 1//. Can anyone enlighten me as to why it isn't? Also, if they are two different variables, how would you distinguish between them in this translation unit?

    Many thanks for any help.

  2. #2
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    It is. External in this case means external to block scope. Notice that extern int i; is within a block, while the int i; that it links to is declared otuside tha block, hence it is external (to the block) linkeage. This is part of the standard to resolve any ambiguities, the example code is extremely poor code to begin with, the standard just defines how it must be dealt with, since it isnt exactly incorrect. The C/C++ standard is a lot like the national electrical code. 99% of it may seem silly because it deals with things that will mostly never come up, but it is there to deal with those oddball situations when they arrise, so there are no amiguities concerning what is and is not proper.
    Last edited by abachler; 01-13-2009 at 04:17 PM.

  3. #3
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    Thanks. That's what I thought.

    But I would understand the statement "There are three objects named i in this program. etc." to mean that there are three different objects and hence that the first and the third are not the same.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So the following program:
    Code:
    #include <iostream>
    static int i = 2;
    int main() {
        int i = 3;
        {
            extern int i;
            std::cout << "This i: " << i << std::endl;
        }
        std::cout << "This i: " << i << std::endl;
        return 0;
    }
    which seems roughly analogous to the code in the standard, doesn't compile -- no suitable extern declaration for the third i is found.

    I would guess the keyword is "visible"; the static int i declaration is not visible, i.e., not in scope (the declaration of the automatic variable removes the entire block from the scope of the static object), and extern must refer to a variable with linkage, and automatic variables have no linkage.

    (Edit: Well, it compiles, but it doesn't link.)

  5. #5
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    It compiles and runs without any problem on my machine:

    This is i: 2
    This is i: 3

    Would the extern keyword not 'unhide' the global i?

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, that's interesting. It compiles and links on my Windows machine, but I cannot get my Mac (with gcc 4.0 and gcc 4.2) to link this program. extern int i is just a declaration, not a definition, so that can't get us into trouble.

    Edit: Comeau's online compiler says:
    Code:
    "ComeauTest.c", line 6: error: external/internal linkage conflict with previous
              declaration
              extern int i;
                         ^
    which makes life even more fun.
    Last edited by tabstop; 01-13-2009 at 07:15 PM.

  7. #7
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    I get a warning "line 2 : 'i' defined but not used". However, if I delete line 2 and put
    Code:
    int i = 2;
    in another translation unit, the compiler doesn't give any warning.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Quantum Random Bit Generator
    By shawnt in forum C++ Programming
    Replies: 62
    Last Post: 06-18-2008, 10:17 AM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  4. Get sense of internal linkage and external linkage
    By gandalf_bar in forum C++ Programming
    Replies: 1
    Last Post: 10-14-2003, 05:57 AM
  5. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM