I thought that extern specifies that function is implemented in other .cpp file or library/object file. But why my code compiles? And is there a difference between previous example and this:
1 2 3 4 5 6 7
// main.cpp
externvoid msg():
int main()
{
msg();
}
Declarations of variables [...] at file scope are external by default.
That doesn't sound right. If you declare an object as not explicitly extern in a header, you get duplicate definition errors. That's not the case with functions.
1 2 3 4 5 6 7 8 9
int a;
int a;
externint b;
externint b;
void f();
void f();
externvoid g();
externvoid g();
int a; isn't just a declaration, it's a definition. Change the linkage to static in the header and you'll see it works fine. The extern in the case of externint b; works because it is not also defining the variable. If you attempt to use b without defining it somewhere (it need not be defined in the translation unit in which it is being used), you will get a linker error saying b is not defined.
void f(); is a declaration, as is externvoid g();. Both must later be defined somewhere (exactly once mind you), else you will get a linker error. This means you can't define it in the header in which it's declared, assuming that header is going to be included in more than 1 .cpp file.
Okay, how do you declare a global without using extern and without also defining it?
Change the linkage to static in the header and you'll see it works fine.
That's something entirely different. You'd be declaring a static global in every translation unit that includes the header, such that changes made to it in one file are not reflected in the other files.
For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//0.cpp
#include <iostream>
staticint a;
int f();
int main(){
a=10;
std::cout <<f()<<std::endl;
return 0;
}
//1.cpp
staticint a;
int f(){
return a;
}
I don't believe you can. If I have a global variable (i.e., there is only one in the whole program), which can only be defined a single time. Assume "foo.h" is included in "foo.cpp" and "main.cpp", with a global variable declared as you describe. Where is it defined: "foo.cpp" or "main.cpp"? It can't be both given the one definition rule, and the variable cannot be linked with the definition from another translation unit without external linkage, so it would be guaranteed that in either "main.cpp" or "foo.cpp", your global variable would be undefined.
That doesn't sound right. If you declare an object as not explicitly extern in a header, you get duplicate definition errors. That's not the case with functions.
I agree with this, but unless I'm missing something, I was under the impression that global variables had external linkage by default and (in C) you may use the static keyword to make them module-scope (I assume this is the same as internal linkage).
Do I have external and internal mixed up or something?
#include <iostream>
#include "myheader.h"
using std::cout;
using std::endl;
int myVar;
void foo()
{
cout << "In myheader, myvar = " << myVar << endl;
myVar = 4;
}
You'll get linker errors when you try to link these, because myVar has external linkage, and is therefore visible across all translation units. If you change myheader.cpp to declare myVar as 'extern int myVar;' (which is only a declaration, not a definition), it works as you expect.
I think Incubbus had it right in their original response to this thread.
Declarations of variables [...] at file scope are external by default.
mean? That the symbol has global scope, or that the symbol may be defined in a separate translation unit? If the former, the sentence is almost meaningless, because all things put in global scope have global scope by default (duh).
Because two people agree with each other does not mean it´s right^^...
Here is a small part of an c++ standard draft:
4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,23) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.
5 If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.
If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern.
If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.
Is there any difference between these two statements? The phrasing would seem to imply so, but I can't find it.