No clue why extern is not working - c++

I'm just testing out how extern works (using MSVC) and I cannot get it to work, no matter what I do:
// Test.h
int externalint = 10
// Main.cpp
void main()
{
extern int externalint;
std::cout << externalint << std::endl;
std::cin.ignore();
}
This results in a linking error, even though I defined it in the header. I do not wish to include the header because the way I read it says it can be in another translation unit and does not need to be included. Am I wrong with the way I am reading it or did I write something incorrectly? If I include the header, it works, as it should, even without the extern declaration.

Header files are usually not translation units but meant to be included by them. That's why header files usually do not "define" variables, since this would lead to multiple definition errors when the header file is included by different translation units (thereby re-defining the variable again and again).
That's where "extern" comes into place, since this is for just "declaring" a variable without "defining" it. "extern" means "will be defined in some other translation unit".
So the usual way is:
// Test.h
extern int externalint; // just declares externalint
// Test.cpp
int externalint = 10; // defines externalint
// main.cpp
#include "Test.h" // importing the declaration of "externalint" defined elsewhere
int main() {
std::cout << externalint << std::endl;
}

Header files are not typically translation units.
Put the definition in a Test.cpp file.
int externalInteger = 10;
Put your main function in Main.cpp file.
#include <iostream>
int main()
{
extern int externalInteger;
std::cout << externalInteger << std::endl;
std::cin.ignore();
}
Compile and link.
g++ -c Test.cpp
g++ -c Main.cpp
g++ Main.o Test.o
For MS, use cl.exe as the compiler instead of g++.

First ask yourself why would you use such a thing as extern. And then you will understand how to use it.
Imagine you would like a piece of code to be called in different programs.
Once from console application and once from an external program.
So you will write Test.cpp.
Now you can use it at console app using main() function and once you build it together with the external program you can use it there too.
Both will use the externalint value of 10 and as long as you update this Test library in both projects like through git. You would have the identical behaviour in both the console application and the external program.
Where is the Test.h you ask?
There you go:
The Test.cpp will be compiled separately from your Main.cpp but you would like to use the variables and functions from your Test.cpp. How does the compiler know what functions are there?
You will let him know.
You simply create an interface -> Test.h.
And then you will include it in your Main.cpp
#include "Test.h"
Example of interface:
//Test.h
int externalint = 10;
But, what if you have more .cpp files interested in this interface?
Then it will be duplicate and it will not compile. Because you cannot initialize the same variable twice.
Luckily you can declare it and announce that the initialization will be done in one of the .cpp files.
// Test.h
extern int externint;
// Test.cpp
int externint = 10;

Related

Linking two files

I have created two basic .cpp files. First one has just one line of code:
int var=10; , and the second one is this:
#include <iostream>
using namespace std;
int main(){
cout<<var;
return 0;
}
I compile my code using gcc -o myprogram file1.cpp file2.cpp & I always get this message:
error: ‘var’ was not declared in this scope
13 | cout<<var;
Does anyone know how to solve this?
If "var" is a one-off, then simply add an extern:
#include <iostream>
using namespace std;
extern int var;
int main(){
cout<<var;
return 0;
}
If your "first .cpp" grows, and you start adding things other modules will want to use, then you'll probably want to:
Define one or more classes
Create a header file for your class definition(s)
Every translation unit must contain a declaration of every symbol it uses. On the other hand, every symbol must have a definition in exactly one translation unit (unless it's explicitly or implicitly inline; then multiple translation units can have definitions as long as they're all the same).
The usual way to do this is to put the declarations for things in a header file, which you then #include into multiple translation units, while putting their definitions in a .cpp file that forms the main body of the translation unit.
In this particular case, you need a declaration of var in the translation unit that contains main. You could put it in a header that gets #included into file1.cpp; i.e.:
file2.hpp:
#ifndef FILE1_HPP
#define FILE1_HPP
extern int var;
#endif
file2.cpp:
#include "file2.hpp"
int var;
file1.cpp:
#include "file2.hpp"
#include <iostream>
int main() {
std::cout << var;
}
Or you just put it into that translation unit manually; i.e.
#include <iostream>
extern int var;
int main()
{
std::cout << var;
}
Either approach is exactly the same from the compiler's point of view (the preprocessor just does text replacement), but the latter tends to be much more difficult for humans to deal with, so you should probably avoid it in general.
Basically the problem was that I used gcc -o myprogram learn.cpp help.cpp instead of g++ -o myprogram learn.cpp help.cpp to compile. Gcc compiler is used for .c files and g++ for .cpp files

In C++, how do I use constant variable defined in one file elsewhere?

I'm c++ beginner.
// a.cpp
int g_x{ 1 }; // that linkage is extern-linkage by default
extern const int g_y{ 2 }; // change the linkage of variable g_y from intern-linkage to extern-linkage
//main.cpp
#include <iostream>
extern int g_x; // forward declaration
extern const int g_y; // forward declaration
int main() {
std::cout << "The value of g_x is " << g_x << '\n';
std::cout << "The value of g_y is " << g_y << '\n';
return 0;
}
Output:
The value of g_x: 1
The value of g_y: 492240950
what is "492240950" ?
I want to output g_y when I execute following cli:
>> g++ main.cpp a.cpp --std=c++14
What should I improve ?
My apologies, answerer!
I have made a mistake source code so I modify it.
In a.cpp: extern const g_y{ 2 } ---> extern const int g_y{ 2 };
I haven't solve above the issue yet.
Although I say again, my desire output is following:
The value of g_x: 1
The value of g_y: 2
I expect that my knowledge relevant to the property of constant variable is lack
The progress of this issue
I removed extern keyword in a.cpp, but I haven't solve the issue.
Its output is not the value of g_y, still 9 digit consecutive number.
Source
Link: https://www.learncpp.com/cpp-tutorial/external-linkage/
Since I want to display the value of g_y in console, I have added its output implementation.
You cannot initialize a variable in the same place as you declare it extern. The entire point of extern is to tell the compiler that the symbol is defined elsewhere.
If a.cpp is providing these variables, then it should define them like this:
int g_x = 1;
const int g_y = 2;
When the linker looks for these symbols which are declared extern in main.cpp, it will then find the ones from the compiled object file for a.cpp.
If the variables are defined as non-extern in another source file as well, then the linker will give an error telling you there are multiple definitions.
It is common practice for any source file that exposes global variables to provide a header file where these variables are declared extern. So, for example, you would have a header a.h with the extern declarations in it, and main.cpp would include that.
I just tried the same thing (g++ 7.5.0 on Ubuntu 18.04) and got the correct values of g_x and g_y. I tried both -O3 and -O0 Is it possible that you just compiled different source files (or versions of the source files) than you thought, or ran the wrong compiled executable? Try recompiling and checking the timestamp before you run it.

Getting 'multiple definition' error and I have no clue why [duplicate]

This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.

Is there a way to create different type but same base inheritance objects defined in a shared library? [duplicate]

This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.

Including .cpp files

I have read in places like here that you have to include .h files and not .cpp files, because otherwise then you get an error. So for example
main.cpp
#include <iostream>
#include "foop.h"
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
foop.h
#ifndef FOOP_H
#define FOOP_H
int foo(int a);
#endif
foop.cpp
int foo(int a){
return ++a;
}
works, but if I replace #include "foop.h" with #include "foop.cpp" I get an error (Using Dev C++ 4.9.9.2, Windows):
multiple definition of foo(int)
first defined here
Why is this?
What include does is copying all the contents from the file (which is the argument inside the <> or the "" ), so when the preproccesor finishes its work main.cpp will look like:
// iostream stuff
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
So foo will be defined in main.cpp, but a definition also exists in foop.cpp, so the compiler "gets confused" because of the function duplication.
There are many reasons to discourage including a .cpp file, but it isn't strictly disallowed. Your example should compile fine.
The problem is probably that you're compiling both main.cpp and foop.cpp, which means two copies of foop.cpp are being linked together. The linker is complaining about the duplication.
When you say #include "foop.cpp", it is as if you had copied the entire contents of foop.cpp and pasted it into main.cpp.
So when you compile main.cpp, the compiler emits a main.obj that contains the executable code for two functions: main and foo.
When you compile foop.cpp itself, the compiler emits a foop.obj that contains the executable code for function foo.
When you link them together, the compiler sees two definitions for function foo (one from main.obj and the other from foop.obj) and complains that you have multiple definitions.
This boils down to a difference between definitions and declarations.
You can declare functions and variables multiple times, in different translation units, or in the same translation unit. Once you declare a function or a variable, you can use it from that point on.
You can define a non-static function or a variable only once in all of your translation units. Defining non-static items more than once causes linker errors.
Headers generally contain declarations; cpp files contain definitions. When you include a file with definitions more than once, you get duplicates during linking.
In your situation one defintion comes from foo.cpp, and the other definition comes from main.cpp, which includes foo.cpp.
Note: if you change foo to be static, you would have no linking errors. Despite the lack of errors, this is not a good thing to do.
You should just include header file(s).
If you include header file, header file automatically finds .cpp file.
--> This process is done by LINKER.
Because of the One Definition Rule (probably1).
In C++, each non-inline object and function must have exactly one definition within the program. By #includeing the file in which foo(int) is defined (the CPP file), it is defined both in every file where foop.cpp is #included, and in foop.cpp itself (assuming foop.cpp is compiled).
You can make a function inline to override this behavior, but I'm not recommending that here. I have never seen a situation where it is necessary or even desirable to #include a CPP file.
There are situations where it is desireable to include a definition of something. This is specially true when you try to seperate the definition of a template from the declaration of it. In those cases, I name the file HPP rather than CPP to denote the difference.
1: "(probably)" I say probably here because the actual code you've posted should compile without errors, but given the compiler error it seems likely that the code you posted isn't exactly the same as the code you're compiling.
Because your program now contains two copies of the foo function, once inside foo.cpp and once inside main.cpp
Think of #include as an instruction to the compiler to copy/paste the contents of that file into your code, so you'll end up with a processed main.cpp that looks like this
#include <iostream> // actually you'll get the contents of the iostream header here, but I'm not going to include it!
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
and foo.cpp
int foo(int a){
return ++a;
}
hence the multiple definition error
So I found that if you are compiling from Visual Studios you just have to exclude the included .cpp file from the final build (that which you are extending from):
Visual Studios: .cpp file > right click > properties > configuration properties >
general > excluded from build > yes
I believe you can also exclude the file when compiling from the command line.
I want to clarify something: including header files is not neccessary to make the linker understand what you want. You can just declare it and it will be linked fine.
main.cpp:
#include <iostream.h>
//not including "foop.cpp"!
int foo(int a);
int main(){
std::cout << foo(4) << std::endln;
}
foop.cpp:
int foo(int a){
return a++;
}
I don't encourage doing like this, but know that headers are not some magic which you have to follow to make the code compile.
Using ".h" method is better
But if you really want to include the .cpp file then make foo(int) static in foo.cpp