So i'm doing some basic OpenGL stuff and for my math functions like vectors, matrices i use the GLM library. I created a header file which is supposed to work with the said library and i noticed it compiles and works as intended without even including the needed headerfiles of the GLM-library.
My simplified example program:
Main.cpp
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
#include "Header.h"
int main(int argc, char* args[]){
Header::test();
return 0;
}
Header.h
#pragma once
#include <iostream>
namespace Header {
void test() {
glm::vec3 vec = glm::vec3(1.0f, 5.0f, 1.0f);
std::cout << vec.x << std::endl;
std::cout << vec.y << std::endl;
}
};
My output:
1
5
How is it possible that I don't need to include the GLM-headers in my "Header.h" file?
For C++ programs, the compiler only compiles the .cpp files as a unit. The header files are "included" into the .cpp files.
So the compiler compiles Main.cpp and when the compiler sees #include "Header.h", then it replaces the #include line with the contents of that file.
Because of how this works, the header file does not need to include everything that's needed. This is because it was included by the cpp file before your header file.
Some quirks about this:
If you do #include "Header.h" in another .cpp file that does not have the GLM header files before it, then it will not compile.
If you took the Header.h file and renamed it to a .cpp file, it won't work because then the compiler will attempt to compile it as it's own unit (which will fail because the GLM files are not there).
.h Files are not compiled. Since you include the glm headers first, when the header.h file is included to the cpp, glm is already included. If you tried to include the header in a separate cpp that didn't have #include <glm.hpp>, it would fail.
You have included the GLM headers already, before you include Header.h.
The compilation unit is your Main.cpp file; header files are not compiled separately.
The C-Preprocessor cpp processes all the # statements before compilation is attempted. Try to run cpp Main.cpp: that will show you the source file that g++ will actually compile.
Related
I have the following question. Supposing I have an header file header.hpp which is include in a test.cpp file. Is it possible to add instructions to the header.hpp file in order to check (maybe at compile time) if some C stdio functions are used in the test.cpp file and in positive case do something specific? For example something like:
header.hpp:
#ifndef HEAD
#define HEAD
#include <iostream>
if ( C stdio functions are used in test.cpp ){
std::cout << "Hey" << "\n";
}
#endif
test.cpp
#include "header.hpp"
#include <cstdio>
int main(){
printf( "Hello\n" ); // C stdio function has been used.
}
Output:
Hello
Hey
No, this is not possible. Neither C++, nor C, work like this, on a fundamental level.
An #include is logically equivalent to physically inserting the contents of the included file into the including file. Doing a cut and paste of your header.hpp into the beginning of your test.cpp replacing the #include accomplishes exactly the same thing.
The resulting code gets compiled from beginning to the end, in order.
When reading the header file, the C++ compiler has no knowledge, whatsoever, of something it hasn't read yet. An #include stops reading the file that it's in, and the included file gets read and compiled, before proceeding.
While following the book C++ For Dummies, I have three files in my CodeBlocks project, main.cpp, Pen.h, and Pen.cpp. They look like this:
main.cpp:
#include <iostream>
#include "Pen.h"
//#include "Pen.cpp"
using namespace std;
int main()
{
Pen MyPen = Pen();
MyPen.test();
}
Pen.h:
#ifndef PEN_H_INCLUDED
#define PEN_H_INCLUDED
//#include "Pen.cpp" // Uncommenting this gives a different error
using namespace std;
class Pen
{
public:
// attributes omitted
// PROTOTYPES:
// other functions omitted
void test();
};
#endif // PEN_H_INCLUDED
Pen.cpp:
#include <iostream>
#include "Pen.h"
using namespace std;
//other function definitions omitted
void Pen::test()
{
cout << "Test successful." << endl;
}
When I run the code as listed above, I get an "undefined reference to `Pen::test()'" error. To fix this, I changed the #include statements at the top of main.cpp to:
#include <iostream>
//#include "Pen.h"
#include "Pen.cpp"
This works as intended and correctly prints out "Test successful."
My question is this: what in the world is the point of putting a function prototype in a header file if I have to import the .cpp file later on anyways?
EDIT: It turns out this was a problem with not knowing how to use Code::Blocks rather than with the C++ language.
Assuming you're using gcc, you can compile and link in one step by supplying multiple .cpp files via the command line.
g++ Pen.cpp main.cpp
clang should be similar.
clang++ Pen.cpp main.cpp
An #include should never reference a .cpp file. At all. There's no good reason to do it. Include your headers and then supply the names of all .cpp files when you compile. If your project gets big and you have too many .cpp files to reasonably list, then it's time to break out a makefile or similar.
In the main.cpp include the header file:
#include "Pen.h"
The Pen.h file it's ok.
You need to add the Pen.cpp file to the project tree.
Go to Project -> Add files... and add Pen.cpp
I want to create a function outside the main.cpp file
i've tried creating a header file but it doesn't work:
Main.cpp:
#include "other.h"
int main() {
MyFunc();
}
Other.cpp
#include <iostream>
#include "other.h"
void MyFunc() {
std::cout << "Ohai from another .cpp file!";
std::cin.get();
}
Other.h
#include <iostream>
#include "other.cpp"
void MyFunc();
nor CPP, G++, GCC compiler work
GCC Compiling error
Errors shown by vs code
You must include a header file and not a C++ file.
And therefore, you need to remove:
#include "other.cpp"
from other.h & use the following command-line for compiling:
g++ -o output main.cpp other.cpp
You'll get it linked and then compiled, then everything should be working fine.
You must remove #include "other.cpp" in header file.
erase the line "#include "other.cpp" in your other.h and you will be fine...
Edit: you also need a header guard...
I've been teaching myself some OpenGL using SFML for creating windows/handling inputs, etc. My main.cpp started getting a bit unwieldy so I decided to start splitting my code up. I created a 4X_vertex.h and a 4X_vertex.cpp (4X is the name of the project) and moved the relevant functions and structs out of my main and into these files. However, when I compile, I get the error
variable or field "drawVertexArray" declared void
which from my research seems to be just an unhelpful message relating to the next error, which is
vertex was not declared in this scope
Here's my list of includes from my main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "4x_vertex.h"
#include "4x_constants.h"
My 4X_vertex.h:
#ifndef _4X_VERT_H
#define _4X_VERT_H
struct vertex{
GLfloat x,y,z;
GLfloat r,g,b;
};
void drawVertexArray(vertex v[]);
vertex* loadVertexData();
#include "4X_vertex.cpp"
#endif
The part of 4X_vertex.cpp that's giving me the trouble:
using namespace std;
void drawVertexArray(vertex v[]){
... openGL stuff...
}
All of this worked before I started moving it around so I'm assuming there's something weird going on with the includes, or something. All help is greatly appreciated!
Just some pointers. Best practice is to divide your project up into multiple source files. Typically, you would use the word "main" in the file name of the main source file (if applicable). So you might have something like...
main.cpp
feature1.cpp
feature2.cpp
tools.cpp
For your other files, you will typically name them after the class they implement. You will most often have both a .h and a .cpp. Put your declarations in the .h and your definitions in the .cpp had have the .cpp include the .h. That might give you...
main.cpp
feature1.cpp feature1.h
feature2.cpp feature2.h
tools.cpp tools.h
The modules that reference one of your classes includes it's .h as well. So, main.cpp might look like...
#include <iostream>
#include "feature1.h"
#include "feature2.h"
using namespace std;
void main(int argc, char **argv)
{ ...
cout << "Done!\n";
}
And feature1.cpp might be...
#include "feature1.h"
#include "tools.h"
feature1_class::feature1_class() { ... }
void feature1_class::AUsefulFeature(int val) { ... }
//etc.
...where feature1.h declares the class, defined constants, etc. f.g.,
#ifndef FEATURE1
#define FEATURE1
#include "tools.h"
class feature1_class
{
public:
feature1_class();
void AUsefulFeature(int val);
int APublicMember;
};
#endif
You may have noticed that tools.h is actually include twice in feature1.cpp. It is included from within the feature1.h and explicitly from the .cpp file. If you use the following pattern in your .h files ...
#ifndef TOOLS_H
#define TOOLS_H
//... do your thing
#endif
... then multiple includes shouldn't cause you any problems. And as you refactor code, it is one less thing to have to worry about cleaning up.
If you have been using a single file for all your source up till now, you may have been compiling like so...
cl main.cpp
Which gives you your .exe and .obj and maybe other files. But with multiple source files involved, it isnt much different. You can say...
cl main.cpp feature1.cpp feature2.cpp tools.cpp
There is much more to learn, but this is a start and helps you on the way to better organization of your coding thoughts.
You need to #include "4X_vertex.h" at the top of your 4X_vertex.cpp file. This will allow the .cpp file to see the declaration for the struct vertex.
In general, each file (both .h and .cpp files) needs to #include any header files which contain declarations for items used in that file. This includes the standard headers and OpenGL headers, as well as your custom ones.
I want to write two program(.h and .cpp) with below code and use .h file in .cpp but when i run it in TC occur below error
.h File
#ifndef ADD_H
#define ADD_H
int add(int x, int y)
{
return x + y;
}
#endif
.cpp file
#include <iostream.h>
#include <conio.h>
#include "Add.h"
void main()
{
clrscr();
cout << "Sum of 3 and 4 :" << add(3, 4);
getch();
}
Error
Unable to open include file "Add.h"
There's a few things you should look into:
the location (search path) of header files is implementation dependent, both for the <> and "" variants - make sure your header file is in that path somewhere.
you may find that you need to use add.h (all lowercase).
you shouldn't generally include code in header files (you should put it in a separate C file and just use the header file to list declarations (or the prototype in your case).
if that's Turbo C you're using (and it probably is, given the clrscr and getch), there's really no excuse not to upgrade to a more modern environment.
You probably just need to add -I. flag to you compile line.
Add.h is not in the includes path of your compiler.
By the way, iostream.h is deprecated, you should include iostream. Also, cout is in the std namespace, so you need a using namespace std; in your .cpp file or, alternatively, use std::cout instead of cout.