11

Do all variables declared in a block have 'no linkage'?

For example:

1:

If I declare a static variable:

void foo()
{
   static int i;
}

Would it have an internal linkage or no linkage? If no linkage, then why make it static?

2:

What happens if I use extern?

/*global scope*/
static int i;

void foo()
{
    extern int i;
}

In this case, what will be the linkage of i?

cpx
  • 17,009
  • 20
  • 87
  • 142
user103214
  • 3,478
  • 6
  • 26
  • 37

2 Answers2

6

Indeed, 'no linkage' at function scope.

The goal is lifetime management: the static has the lifetime of a global static, while it has the visibility (scope) of a local.

Note

In C++ you can also declare statics ('globals') without linkage by enclosing them inside an anonymous namespace. This trick is used commonly in header-only libraries:

namespace /*anon*/
{
    void foo() {}    // only in this translation unit
    int answer = 42; // this too
}

What happens if I use extern?

If you use extern, the declaration is an extern declaration only (nothing is defined). As such, it normally would be expected to external linkage by definition - being defined in another translation unit. (So it acts the same as if when it was declared at global scope). This is similar to local function declarations:

int main()
{
    void exit(int); // equivalent to non-local declaration
}

Note that, in your 2. example, variable i was already declared static and it will therefore not get external linkage. I might get declared in another translation unit without linker conflicts, though.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • "As such, it has external linkage by definition" -- The funny thing is that `extern` doesn't automatically mean external linkage. It does mean name has a linkage, but it can be internal, like in the original example. – Gene Bushuyev Nov 23 '11 at 01:26
  • @ sehe -- #2, where `extern` is used, it actually defines name with internal linkage. – Gene Bushuyev Nov 23 '11 at 01:36
  • @GeneBushuyev: yup, I was slightly confused there. Have updated my answer. Thanks – sehe Nov 23 '11 at 01:52
1
  1. "Would it have internal linkage or no linkage? if no linkage then why make it static?" -- it would have no linkage. static specifies the static storage duration.

  2. "What happens if i use extern?" It will be a declaration of a name with external linkage, and since there is none in global scope, the program will report linkage errors. Edit: Since there is a previous static declaration visible in the scope, the standard says the name "receives the linkage of the previous declaration" 3.5/6, so the i inside foo() will have internal linkage.

Gene Bushuyev
  • 5,512
  • 20
  • 19
  • You mean his second code snippet will have link errors? It worked fine for me – Michael Mrozek Nov 23 '11 at 00:39
  • @Michael Mrozek - "It worked fine for me" is never an answer. What's important is what the standard says. I must say I overlooked previous `static`, so I'm editing my response. – Gene Bushuyev Nov 23 '11 at 00:56