External linkage doesn't work

Pages: 12
Hi,

Facts:
External linkage is make a type identifier visible in any translation unit.
Non-static global variable has external linkage by default and static storage duration. So far so good.

1
2
3
4
//first.cpp
  
int var = 5; // non-static global variable with external linkage by defult;


1
2
3
4
5
6
7
8
9
10
//mainx.cpp
  
#include "stdafx.h"
#include <iostream>

int main()
{
	std::cout << var << std::endl; // var undefinied error
	return 0;
}


This little example result in error when I compile it. So my questions are:

Why I cannot use var in main.cpp?
It is because of diferent scopes ?
If yes whats the relation between scopes and linkage?

I try to understand these so I will be appreciate for carefull explementation with examples.

PS: I know when I used extern keyword in main.cpp I can resolve this error. But I want to understand the concept.
Last edited on
closed account (48T7M4Gy)
#include "first.cpp"


1
2
3
4
5
6
7
8
#include <iostream>
#include "first.cpp"

int main()
{
    std::cout << var << '\n';
    return 0;
}


first.cpp
int var = 999;

999
Program ended with exit code: 0


Last edited on
closed account (E0p9LyTq)
What is external linkage and internal linkage in C++
http://stackoverflow.com/questions/1358400/ddg#1358796
Each translation unit is compiled separately without any knowledge of other compilation units, so when mainx.cpp is compiled there is no way for it to know what var is if it has not been declared.

You should not include .cpp files as suggested by kemort. It will give you an error when you try to link the program because var is defined in multiple translation units. Instead what you would normally do is to create a header file (first.h) that contains an extern declaration.

first.h
 
extern int var;

mainx.cpp
1
2
3
4
5
6
7
#include "fist.h"
#include <iostream>

int main()
{
	std::cout << var << std::endl;
}
Last edited on
closed account (48T7M4Gy)
You should not include .cpp files as suggested by kemort ... because it will give you an error


No such error occurs until you tell Apple, my compiler and linker that @Peter87 because at the moment they're not taking any notice of you.

http://stackoverflow.com/questions/1330114/whats-the-difference-between-using-extern-and-including-header-files
Last edited on
Peter87. In your example is now not needed to use external linkage its enough to you internal. Make a external linkage example without using external keyword. That is what the standard say is possible and I can demonstrate it.
Last edited on
kemort wrote:
No such error occurs until you tell Apple, my compiler and linker that @Peter87 because at the moment they're not taking any notice of you.

Your code will work if you only compile the main cpp file so that first.cpp does not create its own translation unit. But how do you mean other files that need to access var should do? They can't all include first.cpp because that would lead to multiple definitions of var.

Tony321 wrote:
Peter87. In your example is now not needed to use external linkage its enough to you internal. Make a external linkage example without using external keyword. That is what the standard say is possible and I can demonstrate it.

I didn't post first.cpp because it was the same as in your example. It is possible to have a variable with external linkage without using extern anywhere but then you will not be able to use it in other translation units.
Is including a cpp file a fail safe operation? They usually don’t have conditional blocks to prevent circular include dependencies and are not supposed to contain only declarations, but also initialisations or other code that should not be duplicated.
Moreover, we should agree on the meaning of the expression “external linkage”. If we include a file (“a.h”) into another (“a.cpp” or “b.h”, whatever), that file “a.h” will be ‘copied’ into the second (“a.cpp”). That means, in my opinion, that all the declarations in “a.h” enter in “a.cpp” as if they were written there (in “a.cpp”). I won’t call that external linkage.

I think external linkage means tell the compiler that a variable (or a function, or...) we are going to use is already declared in another file, of which we could also ignore the name (ok, it’s a simplification).

So, following Tony321 code:
first.cpp:
1
2
3
4
5
6
7
#include <iostream>

int var = 5; // non-static global variable with external linkage by defult;

void myFunc1() {
    std::cout << "var in first.cpp: " << var << std::endl;
}


mainx.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

extern int var;
extern void myFunc1();

int main()
{
    myFunc1();
    var--;
    std::cout << "var in mainx.cpp: " << var << std::endl;

    return 0;
}


But the real problem is: is this an academic question? Because external storage is something that should be avoided as long as it’s possible – and ever further :-)
closed account (48T7M4Gy)
@Peter87 ROFL My code will only work if I turn my computer on too.
Yeah!!. Exactly this is my problem. It is possible to have external linkage and your cannot use them in other files without using a extern keyword. BUT LET ME QUOTE FROM MSDN.COM:

"An identifier's name with external linkage designates the same function or data object as does any other declaration for the same name with external linkage. The two declarations can be in the same translation unit or in different translation units. If the object or function also has global lifetime, the object or function is shared by the entire program."

SO: Is var external linkage ? YES
Should be possible to use in different translation units ? YES
Is var have a global lifetime ? YES

So its should be shared in entire program. But is doesn't work like that .WHY they don't write it like this : "OK, Guys its can be shared but the ONLY way you can USE that variable, in other translation unit, is to use an extern keyword, there is no other way and there is no other reason of extern linkage existence. "

PS:
@Enoizat I agreed with you. But you again used the extern keyword. So you agreed with me there is no other way to use it in different translation units without "extern" keyword and so there is no other reason of extern linkage existence?




Last edited on
Hi, Tony321.
I’m afraid there’s a little misunderstanding – or perhaps I can’t catch what’s your real problem because of my poor English.

Every file is compiled separately by the compiler, and later the executable is built by the linker.
The linker must be informed (by the compiler) that there are ‘names’ that are to be considered the same in the entire program.
Let’s say it’s what you do when you write ‘extern’: you give the compiler the right hint to add a code that the linker can understand.
Ok, it’s better if I stop here before being mauled by some expert C++ programmer, as well as native English speaker, but I think I have described the gist of the matter.

[…] there is no other way to use it in different translation units without "extern" keyword and so there is no other reason of extern linkage existence?

Well... I’m bound to say I don’t understand the question :-( My bad, I’m sorry.
But I agree that external storage and global scope are dangerous and should be definitely avoided, if possible.
C programmers used to have less choices to avoid them, but a C++ programmer ought be better wonder if there could be a different solution.
Try putting that variable in it's own namespace, in a header file :+)

As Enoizat says it's an academic question.
You are right guys. It's just an academic question. It's not a actual problem in real code I can't go through, I just wanna get it.

I know things like anonymous namespace @TheIdeasMan. I know how to use extern keywords. But forgot extern keyword at all pls !! . I aware of these stuffs. You dont have to clarify these things to me.

Basically, I just want from you one thing and I repeat it once again for you:

You agreed with me if I said, there is no other way to use variable with external linkage in different translation units without "extern" keyword and so there is no other reason of extern linkage existence?

If don't agreed I would appreciate an explanation from you.

Thanks.
Last edited on
closed account (48T7M4Gy)
http://www.cplusplus.com/forum/beginner/208859/
there is no other reason of extern linkage existence?

Is it possible that you are mixing up syntax and concepts?
External linkage itself sometimes can’t be avoided – or, let’s say, it’s a C legacy that was considered important enough to be kept in C++.
The syntax used to achieve external linkage involves the keyword “extern”.

So: if a variable is defined out of every function in a cpp file, it has global scope and external linkage, in the meaning that offers you the possibility to link to it from another file.
But if you want to link to it, you are need to use the keyword “extern”.
The reason is, I think, rather obvious, since you are not expected to know the code inside other cpp files, which could (and often are) already compiled; therefore you could decide to declare another variable with the same name in your file without being aware of what other programmers have done.

Let me explain by examples:

Mr. John Smith writes a cpp file:
1
2
3
4
#include... 
[...] 
int john_global_variable = 666;
[...] 


Mrs. Ann Johnsons, who isn’t even aware of Mr. Smith existence, writes her own cpp file:
1
2
3
4
#include... 
[...] 
int ann_global_variable = 13;
[...] 


I download there already compiled libraries from Internet and decide to use, for my global variables, these names:
1
2
3
4
5
#include... 
[...] 
int john_global_variable;
int ann_global_variable;
[...] 


My code will run smoothly until I decide to take advantage of their (my two variables) external linkage by adding, in another file:
1
2
extern int john_global_variable; // crash! Which one? Enoizat’s or John Smith’s?
extern int ann_global_variable; // crash! Which one? Enoizat’s or Ann Johnsons’s? 


How you can see:
- external linkage is consider useful by Stroustrup & C(++)
- variables declared at file-level scope have (=offer!) external linkage
- to take advantage of external linkage you need to explicitly state “extern”, otherwise your code could conflict with the one written by other, of which existence you could not even being aware.

If that’s not what you were asking... well, I’m afraid I must give up, because I can’t understand the question.
closed account (48T7M4Gy)
And as an adjunct to that piece of sound advice:
http://www.learncpp.com/cpp-tutorial/42-global-variables/
Sorry, let me finish with an (unsolicited) advice: if you dare use a global variable, at least give it a name that has good odds to be unique!
closed account (48T7M4Gy)
You don't have to be sorry for that - it makes eminent sense :)
@Enoizat thanks for exhaustive answer. But actually the sentence " to take advantage of external linkage you need to explicitly state “extern” would be enough :) ..SO I was basically right only way to use in real life the external linkage with global variables is to use extern keyword. The other things you wrote was clear for me before so there was no need to explain me that again, but ok. Becouse your crash in your code is because of multiple definition of these variables and linker don't know which one to choose ..right?
Last edited on
the sentence [...] would be enough

I'm sorry, but I was not sure I had understood what you were asking (I'm not yet completely sure, btw).

linker don't know which one to choose

That was the idea :-)
Let's say "extern" works as a protection, if you prefer.
Pages: 12