I have a problem.
1>------ Build started: Project: SDL Test, Configuration: Debug Win32 ------
1> playa.cpp
1> main.cpp
1> Generating Code...
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\main.cpp(43): warning C4715: 'load_image' : not all control paths return a value
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\main.cpp(43): warning C4715: 'load_image' : not all control paths return a value
1>playa.obj : error LNK2005: "void __cdecl apply_surface(int,int,struct SDL_Surface *,struct SDL_Surface *)" (?apply_surface@@YAXHHPAUSDL_Surface@@0@Z) already defined in main.obj
1>playa.obj : error LNK2005: "struct SDL_Surface * __cdecl load_image(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?load_image@@YAPAUSDL_Surface@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in main.obj
1>playa.obj : error LNK2005: "bool __cdecl load_files(void)" (?load_files@@YA_NXZ) already defined in main.obj
1>playa.obj : error LNK2005: "bool __cdecl init(void)" (?init@@YA_NXZ) already defined in main.obj
1>playa.obj : error LNK2005: "void __cdecl clean_up(void)" (?clean_up@@YAXXZ) already defined in main.obj
1>playa.obj : error LNK2005: "bool __cdecl check_collision(struct SDL_Rect,struct SDL_Rect)" (?check_collision@@YA_NUSDL_Rect@@0@Z) already defined in main.obj
1>playa.obj : error LNK2005: _SDL_main already defined in main.obj
1>playa.obj : error LNK2005: "union SDL_Event event" (?event@@3TSDL_Event@@A) already defined in main.obj
1>playa.obj : error LNK2005: "struct SDL_Surface * image" (?image@@3PAUSDL_Surface@@A) already defined in main.obj
1>playa.obj : error LNK2005: "struct SDL_Surface * screen" (?screen@@3PAUSDL_Surface@@A) already defined in main.obj
1>playa.obj : error LNK2005: "struct SDL_Surface * wall" (?wall@@3PAUSDL_Surface@@A) already defined in main.obj
1>C:\Users\Will\Documents\Visual Studio 2010\Projects\SDL Test\Debug\SDL Test.exe : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I've googled it, buy the problem with everyone else is always some sort of variable, while my problem is with functions.

Recommended Answers

All 24 Replies

1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\main.cpp(43): warning C4715: 'load_image' : not all control paths return a value

The function load_image has returns that do not return a value.

1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\main.cpp(43): warning C4715: 'load_image' : not all control paths return a value

The function load_image has returns that do not return a value.

1>playa.obj : error LNK2005: "void __cdecl apply_surface(int,int,struct SDL_Surface *,struct SDL_Surface *)" (?apply_surface@@YAXHHPAUSDL_Surface@@0@Z) already defined in main.obj

The function apply_surface() is defined more than once in the program.

1>playa.obj : error LNK2005: "struct SDL_Surface * __cdecl load_image(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?load_image@@YAPAUSDL_Surface@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in main.obj

The function load_image() is defined more than once in the program.

etc...

The first two aren't errors tthat mess with the program. I don't know where else they are defined.

not all control paths return a value

This means that you have code that looks like this:

ReturnType load_image(ArgType1 arg1, ArgType2 arg2, ...)
{
    //...

    if (some_condition) return something;

    // What happens if some_condition is false?
    // You don't return anything in that case...
}

The first two aren't errors that mess with the program.

While they don't affect compilation, they might seriously mess your program after you manage to compile it :)

I haven't changed anything here.

bool load_files()
{
    image = load_image( "hello.png" );
    if( image == NULL )
    {
        return false;    
    }
    wall = load_image("box.png");
    if(wall == NULL)
    {
        return false;
    }

    return true;    
}

Well, the compiler said the problem was with load_image, not load_files. The definition of load_files you post here is irrelevant to the problem.

Now, about the other problems (multiple definition of some functions). Maybe you're declaring and defining these functions in a header file and then include that header file in both main.cpp and playa.cpp. If that's the case, either declare these functions inline or put the definitions in a separate cpp file and see what happens.

Oh, my bad.

    SDL_Surface *load_image( std::string filename ) 
    {
        SDL_Surface* loadedImage = NULL;
        SDL_Surface* optimizedImage = NULL;
        loadedImage = IMG_Load( filename.c_str() );
        if( loadedImage != NULL )
        {
            optimizedImage = SDL_DisplayFormat( loadedImage );
            SDL_FreeSurface( loadedImage );
            if( optimizedImage != NULL )
            {
                Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF );
                SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
            }
            return optimizedImage;
        }
        return NULL;
    }

I added the return NULL, but I got the same error.

Well I have playa.h and main.cpp included in playa.cpp and playa.h included in main.cpp.

I added the return NULL, but I got the same error

Hmmm... I don't know then. It looks ok to me. Maybe I'm missing something...

I have playa.h and main.cpp included in playa.cpp and playa.h included in main.cpp.

You shouldn't include main.cpp in playa.cpp.

I removed the inclusion main.cpp in playa.cpp, but there are certain functions in playa.cpp that require defined things in main.cpp. The only way to solve this in my eyes is to move those functions to main.cpp. I'm hoping you can explain another way around this.

Removing #include "main.cpp" got rid of the above errors.

there are certain functions in playa.cpp that require defined things in main.cpp

You mean global variables or other functions? If it's the former, you could modify the functions in playa.cpp to accept these things as arguments. If it's the latter, you could add declarations for these functions at the beginning of playa.cpp.

It's a little complicated.

playa::playa()
    {
        int x = 0;
        int y = 0;
        int xvel = 0;
        int yvel = 0;
    }

    void playa::handle_input()
    {
        if( event.type == SDL_KEYDOWN )
        {
            switch( event.key.keysym.sym )
            {
                case SDLK_UP: yvel -= man_h / 2; break;
                case SDLK_DOWN: yvel += man_h / 2; break;
                case SDLK_LEFT: xvel -= man_w / 2; break;
                case SDLK_RIGHT: xvel += man_w / 2; break;    
             }
          }
        else if( event.type == SDL_KEYUP )
        {
            switch( event.key.keysym.sym )
            {
                case SDLK_UP: yvel += man_h / 2; break;
                case SDLK_DOWN: yvel -= man_h / 2; break;
                case SDLK_LEFT: xvel += man_w / 2; break;
                case SDLK_RIGHT: xvel -= man_w / 2; break;   
            }        
         }
    }

    void playa::move()
    {
        x += xvel;
        if( ( x < 0 ) || ( x + man_w > SCREEN_WIDTH ) )
        {
            x -= xvel;    
        }
        y += yvel;
        if( ( y < 0 ) || ( y + man_h > SCREEN_HEIGHT ) )
        {
            y -= yvel;    
        }
    }

    void playa::show()
    {
        apply_surface( x, y, image, screen );
    }

errors:

1>------ Build started: Project: SDL Test, Configuration: Debug Win32 ------
1>  playa.cpp
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(15): error C2065: 'event' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(15): error C2228: left of '.type' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(15): error C2065: 'SDL_KEYDOWN' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(17): error C2065: 'event' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(17): error C2228: left of '.key' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(17): error C2228: left of '.keysym' must have class/struct/union
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(17): error C2228: left of '.sym' must have class/struct/union
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(19): error C2065: 'SDLK_UP' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(19): error C2051: case expression not constant
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(20): error C2065: 'SDLK_DOWN' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(20): error C2051: case expression not constant
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(21): error C2065: 'SDLK_LEFT' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(21): error C2051: case expression not constant
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(22): error C2065: 'SDLK_RIGHT' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(22): error C2051: case expression not constant
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(23): warning C4060: switch statement contains no 'case' or 'default' labels
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(25): error C2065: 'event' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(25): error C2228: left of '.type' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(25): error C2065: 'SDL_KEYUP' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(27): error C2065: 'event' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(27): error C2228: left of '.key' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(27): error C2228: left of '.keysym' must have class/struct/union
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(27): error C2228: left of '.sym' must have class/struct/union
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(29): error C2065: 'SDLK_UP' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(29): error C2051: case expression not constant
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(30): error C2065: 'SDLK_DOWN' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(30): error C2051: case expression not constant
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(31): error C2065: 'SDLK_LEFT' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(31): error C2051: case expression not constant
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(32): error C2065: 'SDLK_RIGHT' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(32): error C2051: case expression not constant
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(33): warning C4060: switch statement contains no 'case' or 'default' labels
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(40): error C2065: 'SCREEN_WIDTH' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(45): error C2065: 'SCREEN_HEIGHT' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(53): error C2065: 'image' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(53): error C2065: 'screen' : undeclared identifier
1>c:\users\will\documents\visual studio 2010\projects\sdl test\sdl test\playa.cpp(53): error C3861: 'apply_surface': identifier not found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

The errors are just to show which "things" aren't being defined.

It looks like you have to include the appropriate SDL headers in playa.cpp. What are the headers (*.h files) that you include in main? Try including them in playa.cpp too. Also, it looks like you have some global variables (e.g. event). Reading this could help. Though, you should try to minimize the use of global variables in your programs.

That fixed everything but the global variables. Now I'm getting redefinition; different type modifiers in main.cpp.

What global variables did you get this error for? How / where do you define these variables? Did you read the link I mentioned above?

extern const int SCREEN_WIDTH = 640;
extern const int SCREEN_HEIGHT = 480;
extern const int SQUARE_HEIGHT = 22;
extern const int SQUARE_WIDTH = 10;
extern SDL_Surface *image = NULL;
extern SDL_Event event;

All of these are defined in main.cpp and globals.h.

Which will be your problem. You have two sets of definitions for those variables. Remove the declarations from main and include globals.h in main and any other files which need to use the globals. And don't forget to set up some inclusion guards in globals.h if you haven't already.
And you could also lose the extern keyword too. If both sets are defined as externs, that could also be a problem. Not used extern since my C days, but if memory serves you declared the variables in one module and then declared them as externs in another module which used/referenced them. If I'm not mistaken, declaring both sets as externs and giving both sets values will be a problem. Personally I'd avoid using extern and just stick them in a header which can be included in any modules that require them.

If they aren't defined in main.cpp too, then I get error LNK2005's. Inclusion gaurds?

Inclusion guards (or #include guards) will stop your header from being included multiple times:
e.g. globals.h

#ifndef GLOBALS_INCLUDED
#define GLOBALS_INCLUDED
// you'll need to #include the header/s
// required for SDL_Surface and SDL_Event here

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SQUARE_HEIGHT = 22;
const int SQUARE_WIDTH = 10;
static SDL_Surface *image = NULL;
static SDL_Event event;

#endif // GLOBALS_INCLUDED

Then in main.cpp and any other modules that require the globals, you simply use #include "globals.h" and the variables in globals.h should be available/in scope in that module. Also I could be wrong, but you may need to make the non-const variables static (as shown in the snippet above.)

For more info on inclusion guards see this.

Personally I'd avoid using extern and just stick them in a header which can be included in any modules that require them.

Er... That's what I suggested too. And you can't do that without extern, to the best of my knowledge.

About the problem, now:

 extern const int SCREEN_WIDTH = 640;
 extern const int SCREEN_HEIGHT = 480;
 extern const int SQUARE_HEIGHT = 22;
 extern const int SQUARE_WIDTH = 10;
 extern SDL_Surface *image = NULL;
 extern SDL_Event event; 

Don't do this in globals.h. Do this instead:

 extern const int SCREEN_WIDTH;
 extern const int SCREEN_HEIGHT;
 extern const int SQUARE_HEIGHT;
 extern const int SQUARE_WIDTH;
 extern SDL_Surface *image;
 extern SDL_Event event;

Notice that I don't initialize them here. This should be done in main.cpp:

 const int SCREEN_WIDTH = 640;
 const int SCREEN_HEIGHT = 480;
 const int SQUARE_HEIGHT = 22;
 const int SQUARE_WIDTH = 10;
 SDL_Surface *image = NULL;
 SDL_Event event;

I want to clarify something to avoid a potential misunderstanding. JasonHippy's suggestion creates a different set of globals for each module the global header is included in. This, obviously, works fine if you only want global constants. But if you want global variables, it's not enough, as you'll probably want modifications made to a particular global variable in one module to be reflected in every other module. This is why you have to use extern.

Not initializing the variables in globals.h gives me the same errors as before, except now it's also telling me that the variables in main.cpp and globals.h are incompatible with each other.

Post your code. Post the relevant first lines of globals.h, main.cpp and playa.cpp.

globals.h:

#ifndef GLOBALS_INCLUDED
#define GLOBALS_INCLUDED

extern const int SCREEN_WIDTH = 640;
extern const int SCREEN_HEIGHT = 480;
extern const int SQUARE_HEIGHT = 22;
extern const int SQUARE_WIDTH = 10;
extern SDL_Surface *image = NULL;
extern SDL_Surface *screen = NULL;
extern SDL_Event event;

#endif

main.cpp:

#include "playa.h"
#include "globals.h"
int SCREEN_WIDTH = 640;
int SCREEN_HEIGHT = 480;
int SQUARE_HEIGHT = 22;
int SQUARE_WIDTH = 10;
SDL_Surface *image = NULL;
SDL_Surface *screen = NULL;
SDL_Event event;

Nothing is relevant in playa.cpp anymore.

Well, you do initialize your globals in globals.h. You shouldn't be doing this. Also, you forgot some const qualifiers in your main.cpp. Read the relevant post of mine in the previous page again, more carefully this time :P

This fixed it. Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.