Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does "extern const int n;" not work as expected?

My project consists of only two source files:

a.cpp:

const int n = 8; 

b.cpp:

extern const int n;  int main() {     // error LNK2001: unresolved external symbol "int const n" (?n@@3HB)     int m = n;  } 

I know there are several methods to make it work; however, I just wonder WHY it does't work?

like image 461
xmllmx Avatar asked Feb 15 '13 12:02

xmllmx


People also ask

Can a const variable be extern?

Yes, you can use them together. If you declare "extern const int i", then i is const over its full scope.

What does extern const mean?

In a const variable declaration, it specifies that the variable has external linkage. The extern must be applied to all declarations in all files. (Global const variables have internal linkage by default.) extern "C" specifies that the function is defined elsewhere and uses the C-language calling convention.


2 Answers

It's because const implies internal linkage by default, so your "definition" isn't visible outside of the translation unit where it appears.

In this case, by far the best solution is to put the declaration (extern int const n;) in a header file, and include that in both a.cpp and b.cpp. The linkage is determined by the first declaration the compiler sees, so the later definition in a.cpp will have the correct (external) linkage.

Alternatively, you can force the linkage in the definition:

extern int const n = 8; 

Despite the extern, this is still a definition; anything with an initializer outside of a class definition is a definition.

like image 119
James Kanze Avatar answered Sep 30 '22 18:09

James Kanze


const and constexpr variables in C++ have internal linkage (and thus aren't accessible in other compilation unit) if they aren't also declared extern (either in the definition or in a previous declaration).

In C, it isn't the case (well C hasn't constexpr) so your code is valid, and more you can put extern on a definition.

So if you want to write code which is both C and C++ (and the two declarations should probably come from the same header as James pointed out):

// a.cpp extern const int n; const int n = 8;  // b.cpp extern const int n;  int main() {      int m = n;  } 

if you don't

// a.cpp extern const int n = 8; 

is also possible

like image 42
AProgrammer Avatar answered Sep 30 '22 19:09

AProgrammer