I have 3 files in a Visual Studio project: test.cpp, date.cpp and main.cpp -
test.cpp:
int g() { return 0; }
date.cpp:
/*totally empty*/
main.cpp:
#include "test.cpp"
#include "date.cpp"
int main() { return g(); }
I understand that defining functions in a header file leads to violation of One-Definition Rule if header file is called multiple times. But here, I am calling it only once from only one file/translation unit. Why is it still throwing LNK2005?
You should not include test.cpp and date.cpp. Instead, you should write test.h and date.h, and include it:
test.h
int g();
date.h
// Contains prototypes for functions inside date.cpp
main.cpp
#include "test.h"
#include "date.h"
int main() { return g(); }
You are including "test.cpp" in "main.cpp" - this is most likely wrong, as Visual Studio will ALSO compile "test.cpp" as a separate file, and then link "test.obj" with "main.obj" (those are the files generated by the compiler) into "main.exe". When it then finds "g()" in both "test.obj" and "main.obj", it says "Huh? Why have you got two of these" (or, in linker terms "multiple defined symbols").
The solution is to have a "test.h" that declared void g(); and then use that to include into "main.cpp".
Since test.cpp is in the VS Project, it will be compiled and lined in along with main.cpp causing the multiple definitions - unless you take special measure to prevent that from happening, like removing test.cpp from the project or setting it to be "Excluded from Build".
If you rename temp.cpp to test.h you get two benefits:
VS will not automatically compile a .h when it's in a project, since it assumes that the file is intended to be included from other files instead of being stand-alone compiled.
it will be less confusing to programmers about the intended use of the files
Related
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.
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.
I wrote up a quick example today just to see if it would compile and I was actually quite surprised when I found that it did!
Here is the example:
hello.h
#ifndef HELLO_H
#define HELLO_H
// Function prototype
void say_hello();
#endif
hello.cpp
NOTE: This does NOT include "hello.h" like it would in every C++ example I have ever seen in the history of forever!
// #include "hello.h" <-- Commented out. The corresponding header is NOT included.
#include <iostream>
void say_hello() {
std::cout << "Hello!" << std::endl;
}
main.cpp
#include "hello.h"
int main() {
say_hello();
}
I then compiled "hello.cpp" into a static library as follows:
g++ -c hello.cpp
ar -rvs libhello.a hello.o
Then I compiled the "main" application and linked it to the library
g++ -o main main.cpp -L. -lhello
And ran it and it executed fine!
./main
Hello!
While I was surprised... I do understand why this works. It is because the function in "hello.cpp" is not declared static so it has external linkage and can be seen from outside. Making it static will cause the link to fail due to an undefined reference.
So here's the question... If this does work, then why does everyone everywhere ALWAYS include the ".h" header file with the function declarations in the ".cpp" implementation file. Clearly if it is just defining free functions, this is not necessary and everything will work fine if the header file is not included.
So why do we always include it? -- Is it simply a general lack of understanding of how the linker works? Or is there something more?
Let us change your hello.cpp:
// #include "hello.h" <-- Commented out. The corresponding header is NOT included.
#include <iostream>
int say_hello() {
std::cout << "Hello!" << std::endl;
return 0;
}
This will compile just as well as the previous version. It will probably link too - but it isn't right. The return type is wrong.
This is undefined behaviour, but in many common implementations, you will get away with it because you don't use the return value, and it is often returned in a register. However, it doesn't have to be - and you may get very strange errors at run time. Particularly if the difference is a bit more complicated (like returning double when the callers expect int - that will often be returned in a different register).
If on the other hand, you had written:
#include "hello.h"
#include <iostream>
int say_hello() {
std::cout << "Hello!" << std::endl;
return 0;
}
Then the declaration in the header file would not have matched the definition in the CPP file - and you would have got a nice, easy to understand, compiler error message.
In fact, this is such a good idea that GCC will complain if you don't have a declaration of an external function. (And if you have -wall -werror on your command line, it will stop your build.)
If you have a class, you'll want to include it to get the declaration of the class and its members for their definitions to match. Otherwise, you won't be able to separate the definition and declaration.
/// C.h
class C
{
public:
C();
private:
int _i;
};
/// C.cpp
// #include "C.h"
C::C() : _i(42) {} // error: 'C' does not name a type
See it fail on Coliru.
Likewise, if you have a class template or a function template, it usually needs to be in a header so that versions of it can be stamped out later.
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;
Today I had an interview there they asked me can we include .c file to a source file?
I said yes. Because few years back I saw the same in some project where they have include .c file. But just now I was trying the same.
abc.c
#include<stdio.h>
void abc()
{ printf("From ABC() \n"); }
main.c
#include<stdio.h>
#include "abc.c"
int main()
{ void abc();
return 0;
}
Getting an error:
D:\Embedded\...\abc.c :- multiple definition of 'abc'
Where is it going wrong?
I wrote an abc.h file (the body of abc.h is { extern void abc(void); }),
and included the file in abc.c (commenting out #include abc.c). Worked fine.
Do it as follows:
abc.c:
#include <stdio.h>
void abc()
{printf("From ABC() \n");}
main.c:
#include<stdio.h>
#include "abc.c"
int main()
{
abc();
return 0;
}
(no need for the header file)
Then, to compile, you'd only compile main.c. Do not attempt to compile both abc.c and main.c, because then you'd have the abc() function defined twice.
You need to understand that #include is basically "copy-paste", nothing more. If you tell it #include "abc.c", it will simply take the contents of abc.c, and "paste" them in your main.c file. Therefore, using the above for main.c, after the preprocessor processes it, your main.c will look like this (I'm ignoring the #include <stdio.h>s):
#include<stdio.h>
#include <stdio.h>
void abc()
{printf("From ABC() \n");}
int main()
{
abc();
return 0;
}
which is a valid program.
That said you should generally not do this; you should compile all your .c files separately and only then link them together.
Including C files is perfectly valid as long as you do not try to compile the included C file by itself and then link it together with the object file from the C file which included the other file.
If you do so you'll have the same symbol (usually a function) defined in two files which will result in the errors you posted.
If you have multiple source files you usually do not include them but compile them separately. The linker then merges the object files into a single executable (or library).
You can include file with any extension.
In your program, you had re-defined void abc(); in main (). instead just put statement abc ();
You can include anything you like to, the preprocessor doesn't care about the file extensions. It's only some tradition to name the headers ".h" and the source files ".c" or ".cpp".
You only have to be sure, that after compiling the whole project you don't run into linker problems (e.g. giving both "abc.c" and "main.c" to the compiler would result in multiple definitions of your function).