简体   繁体   中英

How can I use extern to share globe variables between source files in C++?

IDE:codeblocks 13.12

--------------main.cpp------------------

#include<iostream>
using namespace std;

extern const int x;

int main()
{
   cout << x << endl;
}

--------------sub.cpp-------------------

extern const int x = 10;

when I try to run the code before , the compiler show the error :

E:\\NewProject\\Test\\main.cpp|8|undefined reference to `x'|

so, who can tell me how to solve this problem? (I have tried create a head file just like:

extern const int x;

and let both cpp file include this head file. but it make no use)

and if I want create a array at main.cpp just like:

int _array[x];

what should I do?

I'm new here, and not good at English. Thanks very much!!

The extern keyword is saying: This is a declaration only.

For a variable, you need exactly one definition, ie. a declaration without extern somewhere else:

// foo.h
extern int i;

// foo.cc
#include "foo.h"
int i;   // definition

// bar.cc
#include "foo.h"
int main () {
  ++i;   // modifies global variable
}

Special Rules for const

A common use case for const variables is that you define constants in a header file and then use them everywhere else in your program:

// my_constants.h
const int NumHoursInDay = 24;
const int NumMinutesInHour = 60;

If these variables were not const , then including my_constants.h into different translation units (source files + their headers) would result in a linker error due to having multiple definitions of the variables.

The standard committee decided that this was going to be a common enough use case that they actually put a special rule for variables declared const , C++ '03 7.1.5/2:

An object declared in namespace scope with a const-qualified type has internal linkage unless it is explicitly declared extern or unless it was previously declared to have external linkage.

This means that each translation unit will have it's own private copy of the const variable. The linker won't try to merge them together and so there won't be an error.

So the first point is that you can actually just remove extern from your exmaples and your code will compile and link correctly, all because of this special behavior of const .

However, for whatever reason, if you decided you do want to declare your variable first and then have a single definition in the project, you may already have noticed that the following will still generate a linker error:

// foo.h
extern const int i;

// foo.cc
const int i = 0;

This is because the linker expects to find a definition for the i in foo.h and as the i in foo.cc has internal linkage (ie. it is invisible outside of that translation unit) the linker won't consider these objects to be the same.

This can be addressed by looking at the end of the quote from the standard:

or unless it was previously declared to have external linkage.

What we need to do is to tell the compiler that i in foo.cc should have external linkage by first declaring it with extern and then defining it without extern .

// foo.cc
extern const int i;
const int i = 0;

And the best way to do this is to include our header file so that we only have the one declaration:

// foo.cc
#include "foo.h"   // contains the extern declaration of 'i'
const int i = 0;

Array Dimension

One final point is that an array dimension needs to be a constant expression . Adding to the confusion here, an extern const variable that is not defined in the current translation unit is not considered to be a constant expression :

extern const int ArrayDim;
int array[ArrayDim];       // Illegal C++

The code may compile, especially if you're using g++, as there is a C language feature called Variable Length Arrays. Behind the scenes the compiler is hiding memory allocations to support this.

As you intend to use your constant across multiple translation units and you need it to be used as a constant expression then the best option is to define your constant in a header file:

// my_constants.h
const int x = 10;


#include<iostream>
#include "my_constants.h"

using namespace std;

int main()
{
   int _array[x];
   cout << x << endl;
}

extern means that your variable is just declared here but defined in another translation unit. So you can have many declaration of your constant extern const int x; but you must have exactly one definition of this constant const int x = 10;

sub.cpp ,只需使用

const int x = 10;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM