I've been trying to figure this out by myself for months, and that's not an exaggeration.
I feel dirty using the methods I am not since things tend to break and get out of scope when they get complex and I cannot find an answer to this anywhere.
I have a project structure as follows:
Project-Directory/
main.cpp
makefile
SDLMain.h // SDL libraries required to be in the project directory.
SDLMain.m // SDL libraries required to be in the project directory.
--- gamestate/
------ clean.cpp
------ gamestate.cpp
------ gamestate.h
------ init.cpp
--- graphics/
------ graphics.h
------ // more .cpp files
--- logic/
------- logic.h
------- // more .cpp files
--- character
------- character.h
------- // more .cpp files
In main.cpp I have:
// C++ Libraries
#include <iostream>
// Graphical Libraries
//#include <SDL/SDL.h>
//#include <SDL/SDL_opengl.h>
// Custom Libraries
#include "character/character.h"
#include "logic/logic.h"
#include "graphics/graphics.h"
#include "gamestate/gamestate.h"
All the .cpp files in character and graphics etc... include their respective header file which shares the same name as the folder. I.e. clean.cpp, gamestate.cpp and init.cpp and all include gamestate.h.
In each folder there is only one header file, recently reorganised from 1 header file per .cpp.
Basically on this new, more structured system I get scope errors when I attempt to compile my project.
Why is that so if my headerfiles are being included after #include <iostream> and the SDL libraries in main.cpp.
I solved the error by inserting this into all header files:
// C++ Libraries
#include <iostream>
// Graphical Libraries
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
But then I am including the same thing over and over again and surely this is bad practice.
Not only this, but gamestate.h contains a prototype used by gamestate.cpp to a function in logic.cpp which gets a scope error unless I implicitly include logic.h in gamestate.h even though logic.h is included in main.cpp before gamestate.h.
I thought #include is meant to drag the contents of header files into scope and the functions it prototypes so the compiler knows what to expect.
Why am I getting all these errors about scoping and functions not existing?
Should I make a global.h and #include all the SDL and <iostream> stuff there?
Why can't I access the function prototyped in logic.h from another file included afterwards in main.cpp?
This is sort of a "you can do it many ways, and none are completely right or wrong" question.
But technically, a source file needs to include all headers that it depends on. So if "gamestate.cpp" needs something in "logic.cpp", then "gamestate.cpp" needs to include "logic.h". If EVERYWHERE that uses "gamestate.h" also needs "logic.h", then "gamestate.h" probably should include "logic.h", but I have worked on systems where the rules are: If you are going to use "gamestate.h", you must include "logic.h" first. Note that "gamestate.cpp" is not compiled inside "main.cpp" (unless you commit the heinous crime of including "gamestate.cpp" inside "main.cpp" - but please don't do that).
I like it when you can just use a header file directly, without having to remember the list of header files you must add before it.
Using a "global.h" is probably a bad idea.
Related
ALWAYS when I start a new class (EX: main.cpp) I need to
#include <iostream>
#include <string>
#include <math.h>
There is a way to make it automatically ? I mean every time when I create a new class they will already be included ?
A cpp file is not a class, it's a source file. A cpp file may include a class, or multiple classes, or no classes. Similar, a header filer is not a librarie, it's just a header file.
Add your includes to a header (.h file), and then your cpp file only has to include that single header to include all those common includes. Visual Studio even has something called a precompiled header, which is exactly meant as such a header with common includes, except that it's precompiled (which means, using that will compile faster than using a regular header). Afaik, you'll still have to include that single header yourself, tho, so you won't get around writing at least one #include ...
My solution is more a workaround than a "real" solution but : You need these lines at least once in your program.
So I'd create a headers_container.hpp file containing stuff my whole program needs, like these #include.
For example :
headers_container.hpp :
#include <iostream>
#include <string>
#include <math.h>
// Some stuff my whole program needs...
in your *.cpp files :
#include "headers_container.cpp"
// Your compiler knows iostream, std::strings and math now
Make sure the path to headers_container.hpp is correct (if the .hpp is not in the same folder as your .cpp
Using this method, you can add one #include in headers_container.hpp and it will update all the .cpp files.
Moreover you can write a small script to generate files (I did the script you can find here : https://gitlab.com/-/snippets/2033889 )
Enjoy your way in programming ! :)
I am currently working on a large-scale financial application.
There are multiple modules that are compiled separately and then combined in a higher-level makefile.
Due to poor design, a lot of the header files include lots of local includes.
My problem is, when I include /src/equity/pdeModels/EqUtil.H inside my current source file /src/rwBatch/calcVol.C, all the includes at the start of EqUtil.H start to break, giving an error: ../../equity/pdeModels/EqUtil.H:15:30: fatal error: ulbase/SpotPrice.H: No such file or directory compilation terminated.
rwBatch and the equity folder are separately compiled and linked together later. Is this a problem with the makefile? Or how should I go about resolving this?
Indepth example:
/src/Module1/file1.C
/src/Module2/folderA/file2.H
/src/Module2/folderB/file3.H
When I write #include "../folderA/file2.H" in file1.C there are errors because of file2.H. At the start of file2.H there are several includes, for example #include "/folderB/file3.H" which, when compiled in file1.C leads to fatal error: /folderB/file3.H: No such file or directory compilation terminated.
Is this a problem with the makefile? Or how should I go about resolving this?
Specifying a path in an #include statement is almost always a bad idea. It takes information needed by the builder but not by the code, and locks it into the code.
As long as there are no name collisions (e.g. folderA/file3.h and folderB/file3.h) you can simply remove those paths. Change these:
// file1.c:
#include "../folderA/file2.H"
// file2.H:
#include "/folderB/file3.H"
to these:
// file1.c:
#include "file2.H"
// file2.H:
#include "file3.H"
And in your makefile (or other build system):
gcc -I/src/Module2/folderA -I/src/Module2/folderB -c /src/Module1/file1.C -o /wherever/file1.o
If there are name collisions, and you have a module that depends on two headers with the same name, you have some options. The simplest -- and probably best -- is to rename one or both of the headers. If you really must, you can put paths into the #include statements, but the paths should reflect the directory structure you use, not the other way around.
I'm a pretty novice programmer, just learning a little bit of c, but I always did it on Linux with gcc and Vim but decided to try using visual studio and I'm getting LNK2005 and LNK1169 errors, I've tried looking up the errors and how to fix them and properly use PCH because I think it would be useful to learn even if my programs are too small to make use of it.
From my understanding I need to #include "stdafx.h" at the top of my source file (called 'helloworld.c') I haven't touched 'stdafx.c' from the default that came when I create the project, I created a header file called 'bitwise.h' and it has one function in it called 'int bw()' I then have 'stdafx.h' and all I added was #include "bitwise.h" In my headerbitwise.h ive tried to include #include "stdafx.h" #include "stdafx.c" #include <stdio.h> and even not including anything. all of these break my program. The only way I can get it to compile is if i comment out//bw(); then my program compiles just fine.
here are the files that I think may be the culprit:
helloworld.c
#include "stdafx.h"
int main()
{
printf("\tHello World!\n");
getchar();
bw(); //If this line is commented out everything works just Honky-Dory
getchar();
return 0;
}
bitwise.h
#include "stdafx.h" //I've tried lots of diffrent lines here, nothing works
int bw()
{
int a = 1;
int x;
for (x = 0; x < 7; x++)
{
printf("\nNumber is Shifted By %i Bits: %i", x, a << x);
}
getchar();
return 0;
}
stdafx.c
// stdafx.cpp : source file that includes just the standard includes
// $safeprojectname$.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include "bitwise.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
This is not much about PCH. You have mixed up header (.h) and implementation (.c) files. What you need to do is split implementation and declaration. You should do following:
rename your bitwise.h to bitwise.c since this is your implementation file, not a header!
create a new file bitwise.h and put only declaration there, it should look like this:
#pragma once
int bw();
Your project should be able to compile after that.
Please also note PCH file should contain includes that are infrequently changed, which is probably not your case since you are including also bitwise.h. You might want to remove this include from stdafx.h and include it into your helloworld.c.
And just a side note, during learning C do not think of including .c file via #include! If it fixes some of your compilation errors, your project design is probably very wrong.
Nitpick: You should not need to #include stdafx.h in bitwise.h, though it should still have a #pragma once.
Your code for bw() should still be in a separate bitwise.c file, not in the header. I think you may be confusing precompiled headers with function inlining? Right now, your code for bw is being compiled into what is supposed to be the dummy stdafx object, and again in the main object, and causing a conflict when linking.
Also, did you remember to mark your stdafx.h as the precompiled header (/Yu), and the stdafx.cpp as... whatever /Yc is supposed to mean? Make sure both options are set for all project configurations for both files in Properties -> C/C++ -> Precompiled Headers.
I got a comprehension issue about precompiled headers, and the usage of the #include directive.
So I got my "stdafx.h" here and include there for example vector, iostream and string. The associated "stdafx.cpp" only includes the "stdafx.h", that's clear.
So if I design my own header file that uses for example "code" that's in vector or iostream, I have to include the header file because the compiler doesn't know the declarations at that time. So why are some posts here (include stdafx.h in header or source file?) saying, it's not good to include the "stdafx.h" in other header files even if this file includes the needed declarations of e.g. vectors? So basically it wouldn't matter to include directly a vector or the precompiled header file, both do the same thing.
I know of course, that I don't have to include a header file in another header file if the associated source file includes the needed header file, because the declarations are known at that time. Well, that only works if the header file is included somewhere.
So my question is: Should I avoid including the precompiled header file in any source file and why? And I am a bit confused, because I'm reading contradictory expressions on the web that I shouldn't include anything in header files anyway, or is it O.K. to include in header files?
So what's right now?
This will be a bit of a blanket statement with intent. The typical setup for PCH in a Visual Studio project follows this general design, and is worth reviewing. That said:
Design your header files as if there is no PCH master-header.
Never build include-order dependencies in your headers that you expect the including source files will fulfill prior to your headers.
The PCH master-header notwithstanding (I'll get to that in a moment), always include your custom headers before standard headers in your source files. This makes your custom header is more likely to be properly defined and not reliant on the including source file's previous inclusion of some standard header file.
Always set up appropriate include guards or pragmas to avoid multiple inclusion. They're critical for this to work correctly.
The PCH master-header is not to be included in your header files. When designing your headers, do so with the intent that everything needed (and only that which is needed) by the header to compile is included. If an including source file needs additional includes for its implementation, it can pull them in as needed after your header.
The following is an example of how I would setup a project that uses multiple standard headers in both the .h and .cpp files.
myobject.h
#ifndef MYAPP_MYOBJECT_H
#define MYAPP_MYOBJECT_H
// we're using std::map and std::string here, so..
#include <map>
#include <string>
class MyObject
{
// some code
private:
std::map<std::string, unsigned int> mymap;
};
#endif
Note the above header should compile in whatever .cpp it is included, with or without PCH being used. On to the source file...
myobject.cpp
// apart from myobject.h, we also need some other standard stuff...
#include "myobject.h"
#include <iostream>
#include <fstream>
#include <algorithm>
#include <numeric>
// code, etc...
Note myobject.h does not expect you to include something it relies on. It isn't using <iostream> or <algorithm>, etc. in the header; we're using it here.
That is a typical setup with no PCH. Now we add the PCH master
Adding the PCH Master Header
So how do we set up the PCH master-header to turbo-charge this thing? For the sake of this answer, I'm only dealing with pulling in standard headers and 3rd-party library headers that will not undergo change with the project development. You're not going to be editing <map> or <iostream> (and if you are, get your head examined). Anyway...
See this answer for how a PCH is typically configured in Visual Studio. It shows how one file (usually stdafx.cpp) is responsible for generating the PCH, the rest of your source files then use said-PCH by including stdafx.h.
Decide what goes in the PCH. As a general rule, that is how your PCH should be configured. Put non-volatile stuff in there, and leave the rest for the regular source includes. We're using a number of system headers, and those are going to be our choices for our PCH master.
Ensure each source file participating in the PCH turbo-mode is including the PCH master-header first, as described in the linked answer from (1).
So, first, the PCH master header:
stdafx.h
#ifndef MYAPP_STDAFX_H
#define MYAPP_STDAFX_H
// MS has other stuff here. keep what is needed
#include <algorithm>
#include <numeric>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#endif
Finally, the source files configured to use this then do this. The minimal change needed is:
UPDATED: myobject.cpp
#include "stdafx.h" // <=== only addition
#include "myobject.h"
#include <iostream>
#include <fstream>
#include <algorithm>
#include <numeric>
// code, etc...
Note I said minimal. In reality, none of those standard headers need appear in the .cpp anymore, as the PCH master is pulling them in. In other words, you can do this:
UPDATED: myobject.cpp
#include "stdafx.h"
#include "myobject.h"
// code, etc...
Whether you choose to or not is up to you. I prefer to keep them. Yes, it can lengthen the preprocessor phase for the source file as it pulls in the headers, runs into the include-guards, and throws everything away until the final #endif. If your platform supports #pragma once (and VS does) that becomes a near no-op.
But make no mistake: The most important part of all of this is the header myobject.h was not changed at all, and does not include, or know about, the PCH master header. It shouldn't have to, and should not be built so it has to.
Precompiled headers are a method to shorten the build time. The idea is that the compiler could "precompile" declarations and definitions in the header and not have to parse them again.
With the speed of todays computers, the precompilation is only significant for huge projects. These are projects with a minimum of over 50k lines of code. The definition of "signification" is usually tens of minutes to build.
There are many issues surrounding Microsoft's stdafx.h. In my experience, the effort and time spent with discovering and resolving the issues, makes this feature more of a hassle for smaller project sizes. I have my build set up so most of the time, I am compiling only a few files; the files that don't change are not compiled. Thus, I don't see any huge impact or benefit to the precompiled header.
When using the precompiled header feature, every .cpp file must begin by including the stdafx.h header. If it does not, a compiler error results. So there is no point in putting the include in some header file. That header file cannot be included unless the stdafx.h has already been included first.
I have project on Qt4.8 and trying to build it with Qt5.1. I receive lots of
#error gl.h included before glew.h
and
#error glext.h included before glew.h
errors. Seems like it was big changes in Qt5 with OpenGL.. All includes are
#include "GL/glew.h"
#include "GL/gl.h"
#include "GL/glu.h"
glew.h is always the first.
Suposing you only use OPENGL calls in a class where you use functions you need to load using GLEW, then this will work.
What i did to fix this is to include all GLEW h's in the .CPP file, but BEFORE the inclusion of the header file (where the QTGUI which in turn contains OPENGL).
So this is the way for me in GLWIDGET.CPP:
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GLWidget.h>
As you can see, my GLWidget is a derived class coming from QGLWidget, which needs to include QTGUI and all of that.
It doesn't matter whether the header is included first in some .h file. Header files are not standalone. What matters is the order that includes are seen from the source file.
You seem to have too many header inclusions (generally speaking, you should keep header-to-header inclusions to an absolute minimum). There's nothing that can be done on our end to fix that; you just need to untangle your header issues.