I know my understanding of #include or how it is compiled is not correct otherwise the code I have would work. I'm confused on why my code needs #include in two locations in order to compile and run correctly.
My main cpp file armperfmon.cpp:
#include "armperfmon.h"
int main(int argc, char* argv[])
{
FILE* pOutFile = NULL;
PrintCounterOptions(pOutFile);
}
main header file armperfmon.h:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "counters.h"
void PrintCounterOptions(FILE* pFile);
second cpp containing function counters.cpp:
void PrintCounterOptions(FILE* pFile)
{
fprintf("print some stuff");
}
second header file for function counters.h
void PrintCounterOptions(FILE* pFile);
The error:
counters.cpp: error: 'FILE' was not declared in this scope
counters.cpp: error: 'pFile' was not declared in this scope
if I enter #include <stdio.h> in the function cpp file then the error goes away and the function compiles/executes as expected. I assumed that in the main.h file when it included <stdio.h> it would be available for use for subsequent FILE* definitions especially because it is included before counters.h is included. As I type this I'm also realizing the more correct include is <cstdio>. If someone could clarify what is wrong with my thought process it would be much appreciated.
It's hard to answer this exactly because you've stripped out all the specific details like filenames but, in brief, C++ source files are compiled independently before the results are linked together, and the "main header" is not seen at all while compiling the "second cpp": it's only the header for your "main cpp file". Indeed, the entire purpose of header files is to serve as a common location for declarations that shall then be #included into multiple translation units, which is what you need to do here by adding the necessary code to your "second header file".
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
Ok so, simply said : I've included a .h into another .h and i get a compilation error telling me that the functions are already defined in main.obj
But, well i've only included Graphics.h one time so how can it be possible that main.obj also defined the Graphics.h functions ?
I got an Error LNK2005 "Already defined in main.obj".
Graphics.h contain functions that many others files will need, but for the moment we have a problem with just one file so I'd like to fix that first.
EDIT : SOLVED by spliting the header, i kept the header for the functions prototypes and I created a new Graphics.cpp for the functions definition
Here are the most concerned files, I've commented the files content so it is readable.
If I'm wrong by commenting please tell me and I'll put it on pastebin or something like that
main.cpp
#include "main.h"
using namespace std;
int main()
{
sMainData data = {};
main_Initialize(data);
while (data.config.window.isOpen())
{
main_Event(data);
main_Update(data);
main_Draw(data);
}
return 0;
}
main.h file :
#ifndef MAIN_H
#define MAIN_H
#include <SFML/Graphics.hpp>
#include "PlayerClass.h"
// Structures...
// Prototypes...
// Functions...
#endif // !MAIN_H
PlayerClass.h file :
#ifndef PLAYERCLASS_H
#define PLAYERCLASS_H
#include "AliveClass.h" // Including the mother
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
#include "Graphics.h" // <-- So here we have our man
//Class definition
#endif // !1
Graphics.h file :
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "SFML/Graphics.hpp"
// Prototypes...
// Functions...
#endif // !GRAPHICS_H
You didn't provide a minimal reproducible example, but my best guess is, you have some function implemented in the header file, while ending up including that header, either directly or indirectly, in more than one cpp file. The result is exactly the same function with exactly the same signature, being compiled in both cpp files, which causes the linker to complain.
Solutions:
Move the function out of the header and into its own cpp file (probably the best)
Find a way to only include the header in one single cpp file (probably the second best in case the header isnt yours and you don't want to touch it)
Make that function inline (probably the easiest, but technically the worst)
Sorry. I'm somewhat new to building larger programs and linking files together and all that good stuff.
My function declarations in my header .h file have std::vector in them. Those function implementations in my header .cpp file also use std::vector. From my understanding, I should just use the "#include " in my header .h file because everything from that file will essentially be pasted into my header .cpp file at compile time. I'm just trying to make sure.
My .cpp file:
#include "PlagiarismDetector_Header.h"
// implementations of functions defined in PlagiarismDetector_Header.h
PlagiarismDetector_Header.h:
#include <iostream> // std::cout, std::endl
#include <vector> // std::vector
#include <string> // std::string
#include <algorithm> // std::swap
#include <math.h> // sqrt()
#include <set> // std::set
#include <map> // std::map
#include <fstream> // std::ifstream
std::vector<std::vector<std::string> > get_file_sntncs(std::fstream&);
std::vector<std::string> get_sntnc_wrds(const std::string&);
double sntnc_smlrty_qtnt(std::vector<std::string>, std::vector<std::string>);
// All the characters that constitute a word
const char LETTERS_ARR[] = {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'."};
const std::set<char> LETTERS_SET(LETTERS_ARR, LETTERS_ARR + sizeof(LETTERS_ARR)/sizeof(char));
You got it pretty much right but consider these aspects:
try to put an include guard in your header file since you may need to have it included twice in row in a future file
consider to push down to the implementation file(s) all constants and functions declarations that do not need to be exposed to the extern modules (whichever file including your header will see them even tough it does not need to use them)
if you use those constants in other files (that will include your header), follow john suggestion and make them extern
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.