Sign in to follow this  
Chrono1081

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

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.");
}
}


Share this post


Link to post
Share on other sites
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.)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmail
*** Source Snippet Removed ***
Is this valid? std::string is not a class yet it is a typedef for a template type.


Forward declaration for std::string:


namespace std
{
template<typename type> struct char_traits;
template<typename type> class allocator;
template<typename type, typename traits, typename alloc>
class basic_string;

typedef basic_string<char, char_traits<char>, allocator<char> > string;
};

Share this post


Link to post
Share on other sites
Quote:
Original post by _fastcall
Quote:
Original post by dmail
*** Source Snippet Removed ***
Is this valid? std::string is not a class yet it is a typedef for a template type.


Forward declaration for std::string:

*** Source Snippet Removed ***

Yes but that is a implementation specific and undefined.

I was 99.9% certain the a forward declaration of a string was not possible and was looking to see if there was a header like iosfwd for the string type. This gotw says it is not possible at all in a portable agnostic fashion using the current standard, is there any change in 0x?

[Edited by - dmail on October 12, 2008 10:16:57 AM]

Share this post


Link to post
Share on other sites
Thank you guys for all the help :) I've been doing some brushing up in console C++ after seeing some things I never worked with yet in your posts. I was just curious, when I hop back to SDL is the engine project I was working on a reasonable thing to do?

The goal was to take everything I was learning (loading images, loading sounds, setting up the screen, etc) and put them in a class for cleaner looking code. That way I can reuse this class for any project I play around with without having to re-write all of the functions that I know I will use each time. I myself do not see a downside to this but then again I am new to SDL and fairly new to programming.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this