You are not logged in.
good evening all,
i have something, that i dont understand in all videos about c++, those i have seen.
extern
it makes a global variable to a variable, that can be used by other cpp files.
but how exactly works it?
i have seen, that here for example
but how exactly does "extern" work?
in the videos i have seen is no include-command to include the other cpp-file. i dont understand, why the include is missing on the videos.
is "extern" a command to set a operating-system wide variable? or how does "extern" work?
Last edited by lo7777799 (2024-12-14 19:15:15)
Offline
extern means the variable is declared elsewhere and that memory not be reserved a second time. You need at least one place where it is not defined as extern. Failure to define it in at least one place in a namespace without the extern keyword is an error. So is doing so more than once is also an error.
Usually one declares external variables in .h files that are included by all source files that need it. Usually the variable is defined in the cpp file the corresponds to the .h file.
Edit: And it is not a 'global' variable. It is an external variable -- that means access can be gained only by using the extern keyword.
Last edited by ewaller (2024-12-14 19:20:11)
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way
Offline
but where is the extern variable then?
is it in a program?
is it in an os-wide environment?
how does a 2nd program knows, where the extern variable is to find?
Last edited by lo7777799 (2024-12-14 19:32:32)
Offline
It is in RAM just like every other static variable. When a static variable is declared memory is set aside and a pointer to that memory location is associated with the variable name. Anything with access to that pointer can read or write the memory. A program can pass that pointer by providing a reference to the memory (a pointer). extern allows a different source file to refer to the memory location by reference by providing that information at compile time (well, link time actually)
Edit: When I say anything, I mean any code in the same program (a bit of an over simplification). Other programs will not have access to that memory space.
Last edited by ewaller (2024-12-14 19:44:30)
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way
Offline
but from where does program 1 knows, where the extern variable of program 2 is, when program 2 were not started to set the variable and is not linked with "include" command to program 1?
Last edited by lo7777799 (2024-12-14 20:53:52)
Offline
There may be multiple source files (.cpp), but it is only one program. Each source file is compiled separately into object files (.o) by the compiler. Finally, the object files are combined to generate a single executable by the linker. When the compiler compiles a .cpp file that declares a variable as external, it means that no memory has been allocated for it and the linker needs to find a reference to it somewhere in one of the other object files. If it cannot find one, then it flags an error.
There is no program 2. Just the source for program 1 distributed across two source files.
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way
Offline
understood
Offline
ah now i understand.
i know now, that 1 cpp programm can be built with more than only 1 cpp files. extern is for communication between different cpp files, if those cpp files are same 1 program.
Last edited by lo7777799 (2024-12-15 20:11:55)
Offline
ah now i understand.
i know now, that 1 cpp programm can be built with more than only 1 cpp files. extern is for communication between different cpp files, if those cpp files are same 1 program.
Extern is some linkage shenanigans. I believe C++ has other ways of dealing with this issue. I have only mostly seen this in C code.
Offline
I believe C++ has other ways of dealing with this issue.
You'll need this to deal w/ global private variables used across files, regardless of ++
Should you use such? Probably not.
Will you at some point? Even if just to maintain ABI and you hate yourself for doing so? Possibly.
Offline
I believe C++ has other ways of dealing with this issue.
You'll need this to deal w/ global private variables used across files, regardless of ++
Should you use such? Probably not.
Will you at some point? Even if just to maintain ABI and you hate yourself for doing so? Possibly.
C and C++ commonly share libraries and this is the only functional use I have seen of the word 'extern'.
Maybe I have not looked at enough code? This use case, for global variables, sounds quite lame even though it does work. Maybe it would sound less lame if we knew why the global variable is being used.
Offline
`extern` has two, very closely related uses. On syntactic level it’s defined as — and don’t be bothered too much with the meaning of those names — a storage class specifier or a linkage specification. Above the former has been described. Where it tells the compiler, that a variable or a function should be one, single instance available across all compilation units.
The other use is defining linkage type and the syntax becomes:
extern string-literal declaration
extern string-literal { declaration-seq }
For example:
extern "C" {
// …
}
That use is not relevant, if you use C++ only. But it becomes crucial, when e.g. you mix C and C++ code.
Each compilation unit exposes a list of “items” it provides for linking. Those items, called symbols, are names. There is a difference in how the names are represented in C and in C++ compilers. In C++ they typically undergo name mangling. If you’d include a plain C header in a C++ program, it’s still compiled as C++ and the names are mangled. But the C object files don’t have the corresponding mangled names, so linking fails. By indicating linkage type, you tell the compiler it should treat those names as if they were using e.g. C linkage, not the normal C++ linkage.
Sometimes I seem a bit harsh — don’t get offended too easily!
Offline
Just thinking out loud.
But, it is possible to limit the scope of a global variable so that it is not global to other modules? For instance?
Have something like:
int global;
int critical_section;
But then, in the other module where you use this variable, don't expose them to the whole file with say
//top of file
extern critical_section;
extern global;
But, instead have the extern within a scope? For instance within a function?
I don't know, but most of the C code I have looked at has been overall mostly functional and care is consequently not taken when using global variables.
Last edited by ReDress (2024-12-17 08:04:18)
Offline
Offline
Each compilation unit exposes a list of “items” it provides for linking. Those items, called symbols, are names. There is a difference in how the names are represented in C and in C++ compilers. In C++ they typically undergo name mangling. If you’d include a plain C header in a C++ program, it’s still compiled as C++ and the names are mangled. But the C object files don’t have the corresponding mangled names, so linking fails. By indicating linkage type, you tell the compiler it should treat those names as if they were using e.g. C linkage, not the normal C++ linkage.
Yeah, thought about this too but wasn't sure that name mangling happens all the time in C++. It seems to me like name mangling is supposed to avoid issues that might arise from usage of language features like overloading(functions, especially).
So, yes, it wasn't clear to me that this happens by default. Thanks for reminder.
Offline
But, it is possible to limit the scope of a global variable so that it is not global to other modules? For instance?
Yes, in more than one way.
In pure C and C++, you can change the linkage. The static in this context is used to make a global variable to have a copy in each compilation unit:
static int var;
This way, if you have var in units “a.c” and “b.c”, it will be a completely separate variable in each of them. The compiler will also be aware that nothing from the outside can write from or read to that variable. That knowledge may be used to generate better code.
Other than that compiler/platform-specific extensions may be used to affect how symbols are visible and used during linking phase. For example GCC has visibility attribute for variables and functions (for compatibility supported by Clang), while MSVC has has `__declspec(dllexport)` on functions. Be aware this is platform-specific and very tightly bound to linking details. Most of the time you’ll not need that. But for completness of the answer this has to be mentioned.
Yeah, thought about this too but wasn't sure that name mangling happens all the time in C++. It seems to me like name mangling is supposed to avoid issues that might arise from usage of language features like overloading(functions, especially).
Strictly speaking it’s compiler-specific. The language itself doesn’t say anything about it. But at least GCC, Clang, and MSVC always mangle names. And the general assumption is that C linkage should be marked, if referring to C code.
Note that there is no simple and elegant way to make this conditional, because the compiler can’t tell in advance if linker will certainly not see a different function with the same name but different types. It must also somehow name symbols in namespaces and class members, work around linker’s naming limitations, and deal with names that are never expicitly mentioned (like template instantiations, callable code it itself generates/expects etc.).
Last edited by mpan (2024-12-18 18:06:15)
Sometimes I seem a bit harsh — don’t get offended too easily!
Offline
Yes, in more than one way.
In pure C and C++, you can change the linkage. The static in this context is used to make a global variable to have a copy in each compilation unit:
static int var;
This way, if you have var in units “a.c” and “b.c”, it will be a completely separate variable in each of them. The compiler will also be aware that nothing from the outside can write from or read to that variable. That knowledge may be used to generate better code.
Does everything seem funny this morning? To me it seems like a way of disabling global variable or "hiding" a variable - heh
Other than that compiler/platform-specific extensions may be used to affect how symbols are visible and used during linking phase. For example GCC has visibility attribute for variables and functions (for compatibility supported by Clang), while MSVC has has `__declspec(dllexport)` on functions. Be aware this is platform-specific and very tightly bound to linking details. Most of the time you’ll not need that. But for completness of the answer this has to be mentioned.
No worries, sounds quite relevant to me.
Strictly speaking it’s compiler-specific. The language itself doesn’t say anything about it. But at least GCC, Clang, and MSVC always mangle names. And the general assumption is that C linkage should be marked, if referring to C code.
Note that there is no simple and elegant way to make this conditional, because the compiler can’t tell in advance if linker will certainly not see a different function with the same name but different types. It must also somehow name symbols in namespaces and class members, work around linker’s naming limitations, and deal with names that are never expicitly mentioned (like template instantiations, callable code it itself generates/expects etc.).
Tell you what? There probably is, it's just easier to load the defaults and they happen to be good enough
Offline
mpan wrote:(…) compiler/platform-specific extensions may be used to affect how symbols are visible and used during linking phase.(…) Be aware this is platform-specific and very tightly bound to linking details. Most of the time you’ll not need that.(…)
No worries, sounds quite relevant to me.
That is unlikely. If you’re just starting with C++, chances are slim you’ll have to deal with platform specific details and writing code tailored for a particular linking scenario. And for normal programs, in particular where you control the entire program, this has no use. For that normal C and C++ linkage control mechanisms are sufficient.
mpan wrote:(…)Note that there is no simple and elegant way to make this conditional,(…)
Tell you what? There probably is, it's just easier to load the defaults and they happen to be good enough
No, it really is not possible. Compilers are almost magical beasts, but even they can’t know the future.
Sometimes I seem a bit harsh — don’t get offended too easily!
Offline
ReDress wrote:mpan wrote:(…)Note that there is no simple and elegant way to make this conditional,(…)
Tell you what? There probably is, it's just easier to load the defaults and they happen to be good enough
No, it really is not possible. Compilers are almost magical beasts, but even they can’t know the future.
Are you of the opinion that compilers have ZERO responsibility towards the binary?
Offline
I don’t get the question. What do you mean by “responsibility”?
Sometimes I seem a bit harsh — don’t get offended too easily!
Offline
That is unlikely. If you’re just starting with C++, chances are slim you’ll have to deal with platform specific details and writing code tailored for a particular linking scenario. And for normal programs, in particular where you control the entire program, this has no use. For that normal C and C++ linkage control mechanisms are sufficient.
When writing software that you can *actually* ship, the line between written code and binaries becomes more and more increasingly thin. It goes without saying that care should be taken to ensure the binaries are in good shape.
Offline