3

Possible Duplicate:
Static variables in C++

// x.h
int i = 3;

// x1.cpp
#include"x.h"
//...

// x2.cpp
#include"x.h"
//...

Above code will give linker error. However If I declare,

//x.h
static int i = 3;

It doesn't give linker error in gcc, even we have the same #include! Are we creating different static int i; for every .cpp file ? Will it cause any silent linking bug (due to same name)?

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • @John, I am compiling .cpp. Let it be for C++ also, as it applies to both C and C++. – iammilind Jul 17 '11 at 16:18
  • possible duplicate of [Static variables in C++](http://stackoverflow.com/questions/3698043/static-variables-in-c), [Variable declarations in header files - static or not?](http://stackoverflow.com/questions/92546/variable-declarations-in-header-files-static-or-not) – Cody Gray - on strike Jul 17 '11 at 16:18
  • 2
    You can't have it both ways. It's either C++ code or it's C code. Pick only one. If you're compiling the code as C++, then it's not a C question. – Cody Gray - on strike Jul 17 '11 at 16:19
  • @iammilind: your question has nothing to do with C++ really. Or if you prefer, it has nothing to do with C. Not every question containing code that could possibly work in either language needs both tags. – John Zwinck Jul 17 '11 at 16:21
  • 1
    i sincerely hope you whipped up this example for demonstration purposes, global variables with names like i are the stuff the road to (debugging) hell is paved with... – fvu Jul 17 '11 at 16:22
  • 2
    @fvu I think we can assume that the real filename isn't x.h either. – SuperElectric Jul 17 '11 at 16:37

6 Answers6

4

When C code is compiled, it's one "translation unit" at a time. Early on, #includes are expanded into the text of the referenced files. So what you've got in the static case is equivalent to x1.cpp saying static int i = 3; and x2.cpp doing the same. And static in this context means roughly "don't share this with other translation units."

So yes, when you use static there you are making two different i variables which have nothing to do with each other. This will not cause a linking error.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
4

int x; is a definition of the entity x. The One Definition Rule of C++ says that any variable that is used shall be defined exactly once in the program. Hence the error.

static says that x has internal linkage. That is, the x's that appear in one.cpp and two.cpp are two different unrelated entities.

The C++ standard says that the use of static in this case is deprecated(As per Steve's comment, in C++0x it's undeprecated). Anonymous namespaces provide a superior alternative.

namespace
{
   int x;
}

Also note that unlike C, in C++ const variables of scalar types also have internal linkage. That is

const int x = 7; // won't give you an error if included in different source files.

HTH

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 1
    Note that the C++0x FDIS un-deprecates this use of `static`. And C++03 never really explained in what way the anonymous namespace version is superior. – Steve Jessop Jul 17 '11 at 16:25
3

Are we creating different static int i; for every .cpp file ?

Yes

Will it cause any silent linking bug (due to same name)?

No. Due to static, they have different names.

If this isn't the behavior you want, you need to use extern in the header file, and allocate the variable in one translation unit (.cpp file)

Yann Ramin
  • 32,895
  • 3
  • 59
  • 82
2

static creates a global variable that is only visible inside the unit.

If you want to use a variable in more than on ecompilation unit, use extern in the header and declare it in the implmenetation without extern.

marc
  • 6,103
  • 1
  • 28
  • 33
0

You get the linker error in your first code example because i is defined and exported in both compilation units. In the second case i is static, so there is no exported symbol because static variables are only visible in the current compilation unit and aren't exported to the linker. In this case you have two independent variables that are both called i.

phlogratos
  • 13,234
  • 1
  • 32
  • 37
0

As written, the code looks like the same i is being accessed by multiple .cpp files, whereas in reality, each .cpp file will have its own copy. This can lead to misunderstandings and bugs.

If you want there to be just one copy of i, the preferred idiom is to wrap it in an accessor function in x.h:

int& GetI() {
  static int i = 3;  // this initialization only happens once.
  return i;
}

If you do want separate copies of i for each .cpp file, a much clearer expression of this is to simply declare i separately in each .cpp file:

namespace {
  int i;
}

Putting it in an anonymous namespace as above keeps it from being accessible from other .cpp files, for safety.

SuperElectric
  • 17,548
  • 10
  • 52
  • 69