1

In my file I can't figure out why I'm getting multiple definition errors. I'm getting them for an "SDL_Surface" called "screen".

screen is located within render.h. I've tried making it extern but it still throws an error. I've looked up quite a bit but I can't find a solution.

Here are the files in question:

main.cpp

//The headers
#include <iostream>
#include <string>
#include <vector>
#include "SDL/SDL.h"
#include "render.h"
#include "Entities.h"

//The surfaces that will be used
SDL_Surface *civilian = NULL;
SDL_Surface *background = NULL;

int main( int argc, char* args[])
{
    //initialize all of SDL systems
    INIT();

    //Load the images
    civilian = load_image("civilian.png");
    background = load_image("background.png");

    //Apply the background to the screen
    apply_surface(0,0, background, screen);

    //apply the civilian to the screen
    apply_surface(180, 140, civilian, screen);

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

    //Wait 2 seconds
    SDL_Delay(2000);

    //free the surfaces
    SDL_FreeSurface(civilian);
    SDL_FreeSurface(background);

    //Quit SDL
    SHUTDOWN();

    return 0;
}

render.cpp

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

bool INIT()
{
    //start SDL
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
    {
        return false;
    };

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

    //if there was an error setting up the screen
    if(screen == NULL)
    {
        return false;
    }

    //set the window caption
    SDL_WM_SetCaption("Zombie!", NULL);

    //if everything initialized fine
    return true;
}

void SHUTDOWN()
{
    //Free images eventually an if statement and array that stores all the images that need to be loaded
    // SDL_FreeSurface(image);

    //Quit SDL
    SDL_Quit();


}

//Optimized image loading function
SDL_Surface *load_image(std::string filename)
{
    //temporary storage for the image that's loaded
    SDL_Surface* loadedImage = NULL;
    //The optimized image that will be used
    SDL_Surface* optimizedImage = NULL;

    //Load the image
    loadedImage = IMG_Load(filename.c_str());

    //If nothing went wrong in loading the image
    if(loadedImage != NULL)
    {
        //Create an optimized image
        optimizedImage = SDL_DisplayFormat(loadedImage);

        //Free the old image
        SDL_FreeSurface(loadedImage);
    }
    return optimizedImage;
}


void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination)
{
    //Make a temporary rect to hold the offsets
    SDL_Rect offset;
    //Give the offsets to the rectangle
    offset.x = x;
    offset.y = y;

    //Blit the surface
    SDL_BlitSurface(source, NULL, destination, &offset);
}

/*bool load_files()
{
    //load the image
    image = load_image( "civilian.png");

    //If there was an error in loading the image
    if (image == NULL)
    {
        return false;
    }
    //if everything loaded fine
    return true;
}
*/

//Event handling
SDL_Event event;

render.h

#ifndef RENDER_H_INCLUDED
#define RENDER_H_INCLUDED

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

SDL_Surface *screen = NULL;

struct Images
{
    std::string filename; //The name of the file to be loaded
    SDL_Surface* image; //set to null when created
    bool optimized; //set to false when created

};

extern Images ImageFiles[10];

//initialize all of SDL subsystems
bool INIT();

//quit SDL
void SHUTDOWN();

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

//Optimized image loading function
SDL_Surface *load_image(std::string filename);

#endif // RENDER_H_INCLUDED

Here's the error:

obj\Debug\render.o||In function Z4INITv':| C:\Users\Joshua\Documents\CodeBlocks\Simulation\Zombie Survival\render.cpp|11|multiple definition ofscreen'| obj\Debug\main.o:C:\Users\Joshua\Documents\CodeBlocks\Simulation\Zombie Survival\main.cpp|20|first defined here| ||=== Build finished: 2 errors, 0 warnings (0 minutes, 1 seconds) ===|

Adi Inbar
  • 12,097
  • 13
  • 56
  • 69
Joshua
  • 90
  • 11
  • You tried putting `extern SDL_Surface *screen;` at the top of `main.cpp`? If I remember correctly you should not have the declaration in the header file either, try declaring it in `render.cpp` – Leonardo Oct 19 '13 at 00:12
  • Never mind having enough rep for multiple links; you should always include the code in the question rather than linking. SO is intended to be a Q&A resource rather than a help site. That means that it's not just about helping you solve your problem, it's also about making the solution available for people who search for it in the future. If you link to code and the link ever becomes unavailable, then the question and answers will be spoiled. – Adi Inbar Oct 19 '13 at 00:34
  • Woops very sorry about that, won't happen again – Joshua Oct 19 '13 at 16:51

2 Answers2

2

Remove SDL_Surface *screen = NULL; from render.h.
Declare SDL_Surface *screen = NULL; in render.cpp.
Declare extern SDL_Surface *screen; in main.cpp.

Since, a commentor asked for an explanation, I am explaining how C++ compiler behave.

C++ compiler compiles each source file (.cpp) as a single compilation unit. If SDL_Surface* screen = NULL; is declared in render.h, each compilation unit will have one copy of the global variable screen (see external linkage). Now, when the linker combines these compilation unit, it sees two copies of the same global variable name and errors out.

Community
  • 1
  • 1
user2784234
  • 451
  • 3
  • 9
  • You might want to add some explanation why. – this Oct 19 '13 at 01:02
  • I knew about that, but i thought that if you declared it extern in the header file it would solve that problem. Seem i was sorely mistaken. I can't thank you enough. – Joshua Oct 19 '13 at 16:57
0

The simplest way to fix this problem is to open render.h and replace

SDL_Surface *screen = NULL;

with

SDL_Surface *screen;

Explanation:

Each time you include render.h from a different .cpp file, it will try to initialize the screen. This is a problem.

I've found that you can define screens multiple times, but you cannot initialize them multiple times.

Ryan Jensen
  • 207
  • 1
  • 9