Connecting Source Files

Hi all,

I've worked through the beginner tutorial of this site, and have a good grasp of all the concepts contained there. Now I'm learning to use SDL.

As my programs get bigger, I would find it helpful to organise sections of my code into different .cpp files, rather than having one giant file. I tried simply calling functions from another file in my project, but that didn't work. Presumably I need to do something with header files? I use Code::Blocks.

If anyone's used Game Maker, I'm experienced with that, so I'm more comfortable with lots of small sections of code (it provides a separate text script for each constructor/destructor of each class).

What is the best etiquette for this? I could make every class/function a separate .cpp, is that overkill? I will shed old habits if someone can give me an idea of what is the best way to organise my programs.

A rough sketch of what I'm trying to get is:

main.cpp:
int main()
{
function1();
function2();
return 0;
}

functions.cpp:
int function1()
{
//code
}

int function2()
{
//code
}

Many thanks
Erain
Maybe you should add some .h files with declarations of this functions. Programmers rather include them, not .cpp files. I think this should help.
Thanks, yes I've got it working using headers.

I created a header file called MyFunctions.h and put my functions in there.

I then simply put #include "MyFunctions.h" in the .cpp file, and it works, great.


One question though. Code::Blocks added 3 default lines in the new header file I created, could someone explain what they do? They are:

1
2
3
4
5
6
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED

//my functions defined here

#endif // FUNCTIONS_H_INCLUDED 
it's an include guard.

See section 3: http://cplusplus.com/forum/articles/10627/#msg49679
That article is just what I needed, thank you very much!
Last edited on
Hmm, I'm having errors relating to scope of declarations, can you let me know what I've done wrong?

Main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "SDL/SDL.h"
#include <string>
#include "Functions.h"

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
SDL_Surface *message = NULL;
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;

int main( int argc, char* args[] )
{

    //code

    return 0;
}


Functions.h:
1
2
3
4
5
6
7
8
9
10
11
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED

#include "SDL/SDL.h"
#include <string>

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination );

SDL_Surface *load_image( std::string filename );

#endif // FUNCTIONS_H_INCLUDED 


Functions.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "Functions.h"
#include "SDL/SDL.h"
#include <string>

SDL_Surface *load_image( std::string filename )
{
  //function code
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
  //function code
}


I used section 1 of that guide as a template, but I'm getting a bunch of "not declared in this scope" errors, and an "expected initalizer" error. If you need full details let me know, but I assume I've simply put something in the wrong place which may be obvious to someone experienced.
Last edited on
There are missing semicolons in Functions.h, at the end of lines 7 and 9.
Syntax, grr.

Well that's changed all the errors to "undefined reference to loadimage/apply surface" in main(). So it's basically just not seeing the functions now.

If I include the .cpp file instead of .h, it works. But I know I'm not supposed to do that.
Last edited on
It sounds like you aren't linking with Functions.o. Are you using GCC? Could you post how you are compiling?
OK, it's working now. I have no idea why, I just clicked random options in the menus related to build targets and kept rebuilding until it didn't error.

I am using GCC, and was just compiling using Code::Blocks default settings, as I don't know what I'm doing with the IDE yet. The only thing I changed in the global settings was Type to GUI application so the console window didn't appear (started with an empty project).

I think it might have had something to do with when I add files/headers it has options to "Add file to active project In build target(s):" and then has checkboxes for Debug/Release. I might have checked them first time round. What are those for and what should I do with them in future?
Last edited on
I think it might have had something to do with when I add files/headers it has options to "Add file to active project In build target(s):" and then has checkboxes for Debug/Release. I might have checked them first time round. What are those for and what should I do with them in future?


Yes. Check those for your cpp files. I don't know why C::B doesn't check them by default -- it's a huge annoyance.

Basically those checkboxes tell the IDE to make the cpp file part of the project. If you leave them unchecked, then the IDE won't use code in that file for building the project (which is why you were getting those errors before)
Hmm, I'm having more trouble with this. I've written a simple program to illustrate.

1
2
3
4
5
6
7
8
9
10
11
12
13
// main.cpp

#include <iostream>
#include <string>
#include "function.h"

const std::string MyConstString = "Hello World";

int main ()
{
  std::cout << returnMyConstString();
  return 0;
}


1
2
3
4
5
6
7
8
9
10
//function.h

#ifndef FUNCTION_H_INCLUDED
#define FUNCTION_H_INCLUDED

#include <string>

std::string returnMyConstString();

#endif // FUNCTION_H_INCLUDED 


1
2
3
4
5
6
7
8
9
//function.cpp

#include <string>
#include "function.h"

std::string returnMyConstString()
{
    return MyConstString;
}



The error returned is:

In function 'std:string returnMyConstString() error': 'MyConstString' was not declared in this scope


But surely I've defined MyConstString as a global constant so that shouldn't be a problem?


When the compiler is compiling function.cpp, it does not read or know that MyConstString is
declared inside main.cpp. It only looks in function.h, <string> and any other headers included
directly and indirectly by those.

So what's the fix? Is it necessary to pass all global variables and constants as arguments to other source files?
No, you can also forward-declare them just like functions (using extern).
However, in this case it makes more sense to move MyConstString to the module that uses it, i.e. function.cpp.
Could you explain how to use extern?

Obviously this program has no need, but the one I encountered the problem with might.

In the actual program I'm working with, I wanted global constants to set things like screen width and height, and then a separate source file to deal with setting up/closing down graphics, as these functions will be the same in the next few programs I write.

Here's an example function which is causing the same errors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bool init()
{
    //Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }

    //Set up the screen
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    //check for errors
    if( screen == NULL )
    {
        return false;
    }

    //If all OK
    return true;
}


In this scenario, SCREEN_WIDTH, etc. are constants in my main source file. The reason I wanted them separate is I might want to change the size of my screen, but the setup will always be the same. So I only wanted to amend things in my main source file, if possible, while leaving useful functions that I will keep on using in a separate .cpp, which can then be used in other projects.

Am I looking at this wrong? Would it be better to define my constants elsewhere?
And I can envisage wanting to use the constants in both source files, potentially.
If you need constants to be shared by more than one .cpp file, put them in a header file.
Topic archived. No new replies allowed.