You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The **extern** keyword is applied to a global variable, function or template declaration to specify that the name of that thing has *external linkage*. For background information on linkage and why the use of global variables is discouraged, see [Program and linkage](program-and-linkage-cpp.md).
31
23
32
-
1. in a global variable or function declaration it specifies that the variable or function is defined (or assigned a value) in another translation unit.
33
-
2. with a "C" argument, it specifies that the function is defined elsewhere and uses the C-language calling convention.
34
-
3. in a template declaration, it specifies that the template has already been instantiated elsewhere. This is an optimization that tells the compiler that it can use the other instantiation rather than creating a new one at the current location. For more information about this use of **extern**, see [Templates](templates-cpp.md).
24
+
The **extern** keyword has four meanings depending on the context:
35
25
36
-
## extern linkage
26
+
1. in a non-const global variable declaration, **extern** specifies that the variable or function is defined in another translation unit. The **extern** must be applied in all files except the one where the variable is defined.
27
+
1. 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.)
28
+
1.**extern "C"** specifies that the function is defined elsewhere and uses the C-language calling convention. The extern "C" modifier may also be applied to multiple function declarations in a block.
29
+
1. in a template declaration, it specifies that the template has already been instantiated elsewhere. This is an optimization that tells the compiler that it can re-use the other instantiation rather than creating a new one at the current location. For more information about this use of **extern**, see [Templates](templates-cpp.md).
37
30
38
-
When the compiler sees **extern** before a global variable or function declaration, it makes a note for the linker that this program element is the same thing as some other element defined elsewhere with the same name. Such a name has external linkage (its name is visible from files other than the one in which it's defined). Declarations of non-const variables and functions at global scope are external by default. See [Program and linkage](program-and-linkage-cpp.md) for more information.
31
+
## extern linkage for non-const globals
39
32
40
-
The **extern**keyword is ignored if the declaration is also a definition. In the following, when the compiler sees the `int foo = 9;`in fileA.cpp, it treats it as a separate name from `foo` in FileB.cpp, and a linker error will be raised because a name can only appear once in a given scope. To fix the error, change `extern int foo = 9;`to `extern int foo;` so that the linker treats this `foo` variable as the same name as the one in fileB.cpp:
33
+
When the linker sees **extern**before a global variable declaration, it looks for the definition in another translation unit. Declarations of non-const variables at global scope are external by default; only apply **extern**to the declarations that don't provide the definition.
41
34
42
35
```cpp
43
36
//fileA.cpp
44
-
externintfoo = 9; //Error. extern is ignored.
37
+
inti = 42; //declaration and definition
45
38
46
39
//fileB.cpp
47
-
int foo = 0;
48
-
```
40
+
externint i; // declaration only. same as i in FileA
49
41
50
-
## Example
42
+
//fileC.cpp
43
+
externint i; // declaration only. same as i in FileA
51
44
52
-
```cpp
53
-
//specifying_linkage1.cpp
54
-
int i = 1;
55
-
voidother();
45
+
//fileD.cpp
46
+
int i = 43; //LNK2005! 'i' already has a definition.
47
+
externint i = 43; // same error (extern is ignored on definitions)
48
+
```
56
49
57
-
intmain() {
58
-
// Reference to i, defined above:
59
-
extern int i;
60
-
}
50
+
## extern linkage for const globals
61
51
62
-
voidother() {
63
-
// Address of global i assigned to pointer variable:
64
-
static int *external_i = &i;
52
+
A **const** global variable has internal linkage by default. If you want the variable to have external linkage, apply the **extern** keyword to definition as well as to all other declarations in other files:
65
53
66
-
// i will be redefined; global i no longer visible:
67
-
// int i = 16;
68
-
}
54
+
```cpp
55
+
//fileA.cpp
56
+
externconstint i = 42; // extern const definition
57
+
58
+
//fileB.cpp
59
+
externconstint i; // declaration only. same as i in FileA
69
60
```
70
61
62
+
## extern "C" and extern "C++" function declarations
63
+
71
64
In C++, when used with a string, **extern** specifies that the linkage conventions of another language are being used for the declarator(s). C functions and data can be accessed only if they are previously declared as having C linkage. However, they must be defined in a separately compiled translation unit.
72
65
73
66
Microsoft C++ supports the strings **"C"** and **"C++"** in the *string-literal* field. All of the standard include files use the **extern** "C" syntax to allow the run-time library functions to be used in C++ programs.
74
67
75
68
## Example
76
69
77
-
The following example shows alternative ways to declare names that have C linkage:
70
+
The following example shows how to declare names that have C linkage:
78
71
79
72
```cpp
80
-
// specifying_linkage2.cpp
81
-
// compile with: /c
82
73
// Declare printf with C linkage.
83
-
extern "C" int printf(const char *fmt, ...);
74
+
extern "C" int printf(const char *fmt, ...);
84
75
85
-
// Cause everything in the specified header files
86
-
// to have C linkage.
76
+
// Cause everything in the specified
77
+
// header files to have C linkage.
87
78
extern "C" {
88
-
// add your #include statements here
89
-
#include <stdio.h>
79
+
// add your #include statements here
80
+
#include <stdio.h>
90
81
}
91
82
92
-
// Declare the two functions ShowChar and GetChar
93
-
// with C linkage.
83
+
// Declare the two functions ShowChar
84
+
// and GetChar with C linkage.
94
85
extern "C" {
95
-
char ShowChar(char ch);
96
-
char GetChar(void);
86
+
char ShowChar(char ch);
87
+
char GetChar(void);
97
88
}
98
89
99
-
// Define the two functions ShowChar and GetChar
100
-
// with C linkage.
101
-
extern "C" char ShowChar(char ch) {
102
-
putchar( ch );
103
-
return ch;
90
+
// Define the two functions
91
+
// ShowChar and GetChar with C linkage.
92
+
extern "C" char ShowChar(char ch) {
93
+
putchar(ch);
94
+
return ch;
104
95
}
105
96
106
-
extern "C" char GetChar( void ) {
107
-
char ch;
108
-
109
-
ch = getchar();
110
-
return ch;
97
+
extern "C" char GetChar(void) {
98
+
char ch;
99
+
ch = getchar();
100
+
return ch;
111
101
}
112
102
113
103
// Declare a global variable, errno, with C linkage.
@@ -132,6 +122,7 @@ extern "C" int CFunc2(); // Error: not the first declaration of
132
122
## See Also
133
123
134
124
-[Keywords](../cpp/keywords-cpp.md)
125
+
-[Program and linkage](program-and-linkage-cpp.md)
135
126
-[extern Storage-Class Specifier in C](../c-language/extern-storage-class-specifier.md)
136
127
-[Behavior of Identifiers in C](../c-language/behavior-of-identifiers.md)
0 commit comments