Extremely puzzling problem. (fatal error C1014: too many include files : depth = 1024

Started by
12 comments, last by Chrono1081 15 years, 6 months ago
Hi guys. I've been out of the programming loop for several months (decided to take some of my math and physics classes before diving back into programming) and I was doing some exercises just to get back into the swing of things and came upon a weird problem that has me completely stumped. I have four files, three header files and one source file. I have the main.cpp which is my main source file, I have my Library.h which has all my #includes, I have my Surfaces.h which is all my SDL surfaces, and I have my SDL_Engine.h which is to set up the screen and such. There is not much to this program as I am just getting it organized but when I compile it I get this error: 1>Compiling... 1>main.cpp 1>c:\documents and settings\owner\desktop\learning projects\sdl\sdl\sdl_engine.h(1) : fatal error C1014: too many include files : depth = 1024 I have tried using inclusion guards, I have tried all kinds of stuff with the code. Other programs I have are set up the same way and do not have this problem. Below is my code. Am I doing something stupid? Or for some reason am I not able to organize my code this way in SDL? I apologize ahead of time I know its long but any help would be greatly appreciated :) Here is main.cpp

//MAIN.CPP

#include "Library.h"

SDL_Event event;

int main(int args, char* argv[])
{
	bool quit = false;
	SDL_Engine myEngine;  //pointer to SDL_Engine?

	myEngine.init();

	while(quit == false)
	{
		if(SDL_PollEvent(&event))
		{
			if(event.type == SDL_QUIT)
			{
				//Quit the program
				quit = true;
			}
		}

		//update the screen
		if(SDL_Flip(screen) == -1)
		{
			return 1;
		}
	}

	SDL_FreeSurface(screen);

	return 0;
}


Here is Library.h

\\LIBRARY.h

#ifndef LIBRARY_SDL
#define LIBRARY_SDL

//SDL Specific Libraries
#include "SDL\SDL.h"
#include "SDL\SDL_image.h"
#include "SDL\SDL_ttf.h"

//C++ Libraries
#include <string>

//User Defined Headers
#include "SDL_Engine.h"
#include "Surfaces.h"

//User Defined Source Files
#include "SDL_Engine.cpp"

#endif //LIBRARY_SDL


Here is Surfaces.h

//SURFACES.h

#ifndef SURFACES_SDL
#define SURFACES_SDL


//Surfaces


SDL_Surface *screen     = NULL;
SDL_Surface *background = NULL;

#endif //SURFACES_SDL


And here is SDL_Engine.h:

//SDL_ENGINE.h

#ifndef SDL_ENGINE_SDL
#define SDL_ENGINE_SDL

#include "Library.h"


class SDL_Engine
{
public:
	bool init();
	
private:
};



bool SDL_Engine::init()
{

	if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
	{
		return false;
	}

	SDL_WM_SetCaption("Learning SDL",0);
	
	screen = SDL_SetVideoMode(1440,900,0,SDL_RESIZABLE);
	if(screen == NULL)
	{
		return false;
	}

	background = IMG_Load("background.jpg");
	SDL_BlitSurface(background,NULL,screen,NULL);
	SDL_Flip(screen);

	return true;
}

#endif //SDL_ENGINE_SDL


I tried looking in books, online, at old programs I wrote, etc. I just can't figure out whats wrong. Everything works fine when I have them all in one CPP file, they even work fine when there is no Library.h file and all of the #includes are in the main.cpp.
Advertisement
You're missing include guards which results in an infinite chain of inclusion. Solution: add include guards to your headers.
I tried using inclusion guards before but it can't find the surfaces I created when I use them. I re-added the inclusion guards in the code above. I just can't figure out whats going on. (I'm sure its something stupid I am overlooking)
Sure was something stupid alright!!!

I was calling the SDL_Engine.h BEFORE I was calling the Surfaces.h *Slaps Forhead*

Thank you for the info about the inclusion guards though I didn't realize they would call an infinite chain.
You include SDL_Engine.cpp in Library.h. I'm guessing you don't have an include guard in a cpp, and you probably shouldn't #include a cpp. You should probably have declarations from SDL_Engine.cpp in SDL_Engine.h. There's probably some sort of recursive inclusion thing going on or something.

As for the error itself:
http://msdn.microsoft.com/en-us/library/ee6t6b6z(VS.80).aspx

Edit: Never mind then.
Library.h includes SDL_engine.h which in turns includes library.h. (I don't think "include-all" headers are very useful.) Also you shouldn't include cpp files and implement methods in headers (outside class declaration it should probably require the inline keyword?)

Quote:
I was calling the SDL_Engine.h BEFORE I was calling the Surfaces.h *Slaps Forhead*


I believe headers should be designed so that they can be included any order, as long as every file sees what it needs to see.
0) Don't include source files from headers!!! The way to get the SDL_Engine.cpp code to compile is to compile it explicitly, and then *link* that code with the main code.
1) With proper design, you won't need to worry about the order of include files. One aspect of this is that your headers shouldn't have anything "concrete" in them, such as global variables, and ideally not function implementations. For globals, you want to declare them, as 'extern', in the header, and define them in exactly one (usually, the corresponding one) .cpp file. But we won't need to do that here, for reasons explained further below.
2) Proper design involves avoiding these massive "just include everything to make sure I have everything" include files. It only ultimately bites you in the butt. Actually, in general, don't include things until you know you need them.
3) There's no reason for the SDL_event in main() to be a global variable; there's only one function hanging around that could possibly use it.
4) Your code is fine for instantiating the SDL_Engine; don't dynamically allocate when you don't need to.
5) Don't write 'init' functions; use constructors. That's what they're there for.
6) As it stands, if the SDL_Flip fails, you won't get to free the surface. The surface in question should be the responsibility of the SDL_Engine, though, because that's who inits it. Thus, use the destructor of that class to make the SDL_FreeSurface call. Since that destructor will always be called, there is no problem.
7) Since it's the engine's responsibility to track the surface, it should be the engine's responsibility to flip it, too. You can indicate failure by throwing an exception; since nothing catches it, this will terminate the program, but it will do it in a controlled, safe way. In fact, it ought to *hold* the surface, too.
8) Use a while loop to process events, because you can accumulate more than one event in the same game loop.
9) Don't be afraid to make helper functions.
10) There is no need to return explicitly at the end of main(). main() is a special case in C++.
11) Use forward slashes in paths to file names, even though DOS uses backslashes internally. C++ will translate them for you automatically, and it avoids having to double up the backslash characters to avoid problems with string escape characters.

//MAIN.CPP#include "SDL/SDL.h" // for the Event functionality#include "SDL_Engine.h"// Returns whether or not the game should keep running.bool handleEvents() {	SDL_Event event;	while (SDL_PollEvent(&event)) {		if (event.type == SDL_QUIT){			return false;		}	}	return true;}int main(int args, char* argv[]) {	// For flexibility, I pass the name of the background image as a parameter.	SDL_Engine myEngine("background.jpg");	// See how neat this becomes now:	while (handleEvents()) {		myEngine.flip();	}}


//SDL_ENGINE.h#ifndef SDL_ENGINE_SDL#define SDL_ENGINE_SDL#include "SDL/SDL.h"#include "SDL/SDL_image.h"#include "SDL/SDL_ttf.h"class std::string; // a forward declaration.class SDL_Engine {	// I'll explain these two lines later	SDL_Engine& operator=(const SDL_Engine&);	SDL_Engine(const SDL_Engine&);	SDL_Surface* screen, background;	public:	SDL_Engine(const std::string& background_name);	~SDL_Engine();	void flip();};#endif


//SDL_ENGINE.cpp#include <string>#include <stdexcept>SDL_Engine::SDL_Engine(const std::string& background_name) {	if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {		throw std::runtime_error("SDL Init failed.");	}	SDL_WM_SetCaption("Learning SDL", 0);		screen = SDL_SetVideoMode(1440, 900, 0, SDL_RESIZABLE);	if (!screen) {		throw std::runtime_error("SDL Init failed.");	}	background = IMG_Load(background_name);	SDL_BlitSurface(background, NULL, screen, NULL);	SDL_Flip(screen);}~SDL_Engine() {	if (screen) { SDL_FreeSurface(screen); }	if (background) { SDL_FreeSurface(background); }}void flip() {	if (SDL_Flip(screen) == -1) {		throw std::runtime_error("SDL flip failed.");	}}
Wow thank you for all the help guys :)

Thank you Zahlman for giving me the clean up advice. I'm fairly new to SDL and haven't worked a lot with splitting up files and such so I figured now was the time to learn.

My main goal with this project was to take what I learned in SDL and make it easier to access and less messy. (I used to have many many functions piled all around the main(). Not very efficient or sightly.)
Just to note that you should not call SDL_FreeSurface() on the pointer returned by SDL_SetVideoMode(). This surface is freed by SDL_Quit(), SDL_QuitSubsystem(SDL_INIT_VIDEO) or by subsequent calls to SDL_SetVideoMode().

In addition, you can safely pass a NULL pointer to SDL_FreeSurface(), it is documented that the function will do nothing in this case.
class std::string; // a forward declaration.

Is this valid? std::string is not a class yet it is a typedef for a template type.

This topic is closed to new replies.

Advertisement