#include .h or .cpp file? - c++

So I have this weird looking problem: my very basic program generates an error message (undefined reference to 'foo::foo(int)') when i import the .h file of a separate class. However, when I change the import file to .cpp, it all works.
Now, I've read a little, and seen a few video tutorials, and they all say the same: import the .h file. So why doesn't it work?
I use Code::Blocks, where i compile and run(no command lines), in Windows 7. I do suspect that something isn't set up quite right, however, I do want to know for sure if it is my code that fails.
Main.cpp:
#include <iostream>
#include "Foo.h" //This don't work. If i include Foo.cpp it does.
using namespace std;
int main()
{
Foo k(10);
cout << k.getInt() << endl;
}
foo.h:
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Foo(int tall);
int getInt()const;
protected:
private:
int m;
};
#endif
Foo.cpp:
#include "Foo.h"
Foo::Foo(int tall)
: m(tall)
{
//ctor
}
int Foo::getInt()const
{
return m;
}

You need to compile both main.cpp and foo.cpp and link the 2 resulting object files together.

You are failing to compile and/or link the Foo.cpp file when you do your linking step. I'm not familiar with Code::Blocks though, so I can't tell you how to fix it.

Right-click on your .cpp file and go to properties. On build tab make sure compile, link, debug, and release are checked.

Related

should pragma once be on top of every header as default

I'm learning C++ and I have encountered (and fix) what seems to be a very classic problem :
g++ main.cpp A.cpp B.cpp -o out
In file included from B.h:1,
from main.cpp:3:
A.h:1:7: error: redefinition of ‘class A’
1 | class A {
| ^
In file included from main.cpp:2:
Which from a quick research (assuming I understood it correctly), happens because the #include operation is not "idempotent" (a term I discovered with this problem).
To illustrate my question I propose a minimal working example.
main.cpp
#include "A.h"
#include "B.h"
#include <iostream>
int main () {
std::cout << "Hello world" << std::endl;
A a;
B b(a);
return 0;
}
A.h
#include <iostream>
class A {
public:
void test();
};
A.cpp
#include "A.h"
void A::test () {
std::cout << "test" << std::endl;
}
B.h
#include "A.h"
class B {
public:
B(A);
};
B.cpp
#include "B.h"
#include <iostream>
B::B(A a){
a.test();
}
Compiling the program with g++ main.cpp A.cpp B.cpp or more specifically g++ -c main.cpp will fail with the error shown above.
I understand that the compiler transcludes the header of "A" twice when compiling main.cpp (once at main.cpp:1 and once again at B.h:1 during its own inclusing at main.cpp:2). Effectively, the compiler 'sees' the definition of class A twice and thinks we are defining A twice.
What I Fail to understand is the include guards:
To fix this, one may use the keyword: pragma once at the top of the file that is included more than once as such:
A.h fixed with #pragma once
#pragma once
#include <iostream>
class A {
public:
void test();
};
Allowing the program to compile nicely.
To me this suggest that I should start every header with #pragma once !!! Which can't be right is it? Is it common practice? If so, Is there a way to do that at compile time instead (as a flag for instance)?
If I don't, I may not use object A as member of class A nor pass it as argument to B (as in the constructor of B in my example) if such A and B could be used individually in another file; unless I add #pragma once reactively every time the problem pops up which seems "dirty" to me. Furthermore, I would not be able to share my sources with anyone in fear they encounter the situation with two of my objects without having to add pragma once in my files themselves.
What Am I missing? Is there a way to avoid the problem altogether?
To me this suggest that I should start every header with #pragma once !!! Wich can't be right is it?
It can be right. Although it may in theory be a slight exaggeration.
Is it common practice?
Yes, it is. It is fairly universal if we include the other option of using a macro header guard into same practice.
If so, Is there a way to do that at compile time instead (as a flag for instance)?
If you mean, is there a way to make the pre-processor treat every included file as if they contained the pragma whether they have any form of header guard or not then no, there is no way to do that in C++.
In theory, you could write your own pre-processor that does this. However, although such pre-processor would be relatively simple, I would still consider that an unnecessarily complicated solution in relation to the benefit.
unless I add #pragma once reactively every time the problem pops up which seems "dirty" to me.
Is there a way to avoid the problem altogether?
There is a simple way to pre-emptively solve this problem, which you already mentioned: Add the pragma or a traditional macro header guard on top of every header file. There is no need to wait for problems to pop up. Just do this, and your worries are gone.
You can use #pragma once or the more "traditional" include guard.
As you guessed, it should be present in each header file.
In this example you provided:
#pragma once
#include <iostream>
class A {
public:
void test();
};
is not guaranteed to work on all environments. (Like other comments have mentioned.) As well as Circular Dependices.
However using two preprocessor directives: #ifndef and #endif (include guards)
prevents the header file from accidentally being included more than once.
The #ifndef A_H tells the preprocessor to look for a constant named A_H that has not been created with the #define directive.
Now if A_H constant has not been defined then these following lines will be included in the program:
class A {
public:
void test();
};
For example using ifndef and #endif:
#ifndef A_H
#define A_H
class A {
public:
void test();
};
#endif

Undefined reference to class member function when using more than 1 source file

I'm trying to learn how to seperate header and implementation files but it is not working even though i tried to keep it as simple as possible
header file
// foo.h
#ifndef FOO_H
#define FOO_H
struct Foo{
void bar();
};
#endif
implementation file
// foo.cpp
#include "foo.h"
#include <iostream>
void Foo::bar(){
std::cout << "test";
}
main file
// test.cpp
#include <iostream>
#include "foo.h"
int main(){
Foo foo;
foo.bar();
}
when i try to compile this, it throws an error
test.cpp:(.text+0x15): undefined reference to `Foo::bar()'
In order to compile multiple files, you would add both .cpp files to your project under the same target. Then your DEV C++ IDE will automatically add both files to the build and link them together.
On the completely, different note, Please avoid using DEV C++, it is very very old and hasn't seen updates in years. I'd recommend CodeBlocks instead.
You didn't tell us how you're compiling your code, but you need to compile foo.cpp in addition to test.cpp. If you're using GCC, the command is:
g++ test.cpp foo.cpp -o test
You forgot to add void in the definition of bar (in implentation file).
It should be void Foo::bar() {....

Not including the corresponding header (.h) file in the implementation (.cpp) file still compiles?

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.

Multiple declaration vs not defined

I'm trying to import variables from a file that are used in a class in other file and ultimately import that to yet another file and compile.
Let me show what the reproduction of the problem looks like:
arrayFile.hpp
int arr[] = {
1,2,6,5,4,3
};
classFile.hpp
#include <iostream>
using namespace std;
#include "arrayFile.hpp"
class MyClass{
private:
int v1;
public:
MyClass();
void setV(int v);
int getV();
int funcM();
};
classFile.cpp
#include <iostream>
using namespace std;
#include "classFile.hpp"
MyClass::MyClass(){};
void MyClass::setV(int v){
v1 = v;
}
int MyClass::getV(){
return v1;
}
int MyClass::funcM(){
return v1*arr[0];
}
mainfile.cpp
#include <iostream>
using namespace std;
#include "classFolder/classFile.hpp"
// #include "classFolder/arrayFile.hpp"
// should i include this?
int main(){
MyClass c;
c.setV(3);
cout<<c.funcM()<<endl;
cout<<arr[0]<<'*'<<c.getV()<<endl;
}
The objective is to acess the array from both the classFile.cpp and mainfile.cpp, but I'm not managing to do this.
If I don't include arrayFile.cpp in mainfile.cpp:
/tmp/cce4ZHbp.o:(.data+0x0): multiple definition of `arr'
/tmp/ccmsYdmt.o:(.data+0x0): first defined here
If I do:
In file included from mainfile.cpp:5:0:
classFolder/arrayFile.hpp:1:9: error: redefinition of ‘int arr []’
int arr[] = {
^
In file included from classFolder/classFile.hpp:3:0,
from mainfile.cpp:4:
classFolder/arrayFile.hpp:1:5: note: ‘int arr [6]’ previously defined here
int arr[] = {
^
I've was able to get the compiler to tell me arr[] was undefined too, but am unable to reproduce this error.
What am I doing wrong?
The real issue I'm facing requires me to import an array and a struct to a class, and this class is imported to yet another bigger class, this last class is finally used by main. This is my best at reproducing it. I don't know how to fix this.
You should not include arrayFile.hpp inside your classFile.hpp. Include it only in classFile.cpp. Also, in mainfile.cpp (before main function) add line
extern int arr[];
This line tells the compiles that array of type int called "arr" will be defined in some other cpp file that will be linked together with mainfile.cpp.
Compile your program like this:
g++ -std=c++11 -c main.cpp classFile.cpp
g++ -std=c++11 main.o classFile.o
./a.out
First line compiles your files individually (creating main.o and classFile.o files)
Second line links them together creating one executable file (a.out)
Third line runs the executable file
Since adding new files makes this compilation process complicated, I suggest using a Makefile.
Broadly, it is not a good idea to define variables in a header file - assuming said header file will be included by multiple source files.
When you compile your project, the preprocessor handles "#include" statements by literally placing the content of the included header file in the file including it.
E.g.:
// foo.h
#ifndef FOO_H
#define FOO_H
typedef int myInt;
#endif
.
// main.cpp
#include "foo.h"
int main( int argc, char* argv[] )
{
return 0;
}
.
// preprocessor output
typedef int myInt;
int main( int argc, char* argv[] )
{
return 0;
}
This is a simplification - but good enough for illustrative purpose.
So what's happening in your example?
arrayFile.hpp is included by classFile.hpp which is included by classFile.cpp and mainfile.cpp. It may be helpful to consider the include-tree:
arrayFile.hpp
|
classFile.hpp
/ \
classFile.cpp mainfile.cpp
Think about what I said RE: replacing includes with the included file content and see if you don't agree when I say that classFile.cpp and mainfile.cpp both end up with a definition of your arr array.
What happens next when you're compiling your project? The compiler compiles your source code - specifically, the preprocessor output - to object files. E.g. the preprocessed classFile.cpp becomes classFile.o and the preprocessed mainfile.cpp becomes mainfile.o.
Finally, object files (or the libraries they are archived into) are linked to form your executable.
When the linker tries to link classFile.o and mainfile.o it will discover that both have arr defined in them. Thus you get your multiple definition linker error - not a compiler error.
So: if a header file is included - directly or indirectly - by multiple source files, you'll run into linker errors if the header file defines variables. This is why, it is standard practice to declare variables in header files and define them in one source file.
Hope that helps.

When to include foo.h in foo.cpp

I have frequently seen people #include "foo.h" at the top of "foo.cpp". It looks like you could always do this, but people don't. So there must be some reason behind the choice.
When should I #include the header (foo.h) inside the source file (foo.cpp)?
The reason to put it at the top is simply to check that its contents don't depend on any other headers. For example:
// foo.h
void f(std::vector<int>& v);
// foo.cpp
#include <vector>
#include "foo.h"
// foo1.cpp
#include "foo.h"
#include <vector>
In foo.cpp, there's no problem: everything compiles just fine. foo1.cpp, on the other hand, won't compile, because foo.h uses std::vector without an include directive.
Having every header file compilable on its own avoids mysterious failures that otherwise occur when you change include directives in a file that has nothing to do with foo.cpp. These are sometimes hard to identify, and they're always frustrating.
You need to include the header if you're using anything inside the header.
For example, if you need to create foo someObject = new foo(); in your main method, you need to include the header foo.hthat has that class definition.
You only need to include things that you know you're going to use.
You can include a header file whenever you want.
Anyway, suppose you have a file main.h similar to the following one:
#ifndef FOO_H
#define FOO_H
struct S { };
#endif
Now, this main.cpp works just fine, as you mentioned:
void f() { }
#include "foo.h"
int main() { f(); }
Anyway, if I slightly change the main.cpp it doesn't work anymore:
void f() { S s{}; }
#include "foo.h"
int main() { f(); }
The problem is that S is declared after its first use and it is not visible when the definition of f is encountered for the first time.
So, the rule of thumb could be - include a header immediately before you start using something (let me say) imported by that file.
Anyway, this could quickly lead to messy files with #include directives spread all around and a common practice is to simply put all of them at the top of the file and that's all.