Search code examples
c++extern

I am getting an error of redefinition while using extern header file


I am getting an error of redefinition while using extern, but I was also told, that extern variable should be used like this, why I am getting this error and how should I use extern in this case so it will work? (I can use this variable even if I don't specify it in Tab.cpp, but I am getting error of finding one or more symbols, which was defined 2 times.)

Files:

Tab.h:

#pragma once

#include "wx/wx.h"

class Tab : public wxFrame {
wxDECLARE_EVENT_TABLE();

void close(wxCommandEvent& evt);
void init();

public:
    Tab();
};

Tab.cpp:

#include "Tab.h"
#include "ids.h"
#include "wx/wx.h"

int maxid;

wxBEGIN_EVENT_TABLE(Tab, wxFrame)
    EVT_BUTTON(2, Tab::close)
wxEND_EVENT_TABLE()

Tab::Tab() : wxFrame(nullptr, maxid++, "ERIS 2") {
    init();
}

void Tab::close(wxCommandEvent &evt) { this->Close(); evt.Skip(); }

void Tab::init() {
    wxGridSizer* sizer = new wxGridSizer(10, 10, 0, 0);

    for(int x = 0; x < 10; ++x)
        for(int y = 0; y < 10; ++y) {
            sizer->Add(new wxButton(this, maxid, _(std::to_string(maxid))), wxEXPAND | wxALL);

            ++maxid;
        }
    

    this->SetSizer(sizer);
    sizer->Layout();
}

ids.cpp:

#include "ids.h"

std::vector<Object> ids;

Object& search(const char* name) {
    for(std::vector<Object>::iterator it = ids.begin(); it != ids.end(); *++it)
        if((*it).name == name)
            return *it;
}

Object& search(int id) {
    for(std::vector<Object>::iterator it = ids.begin(); it != ids.end(); *++it)
        if((*it).id == id)
            return *it;
}

void add(Object& obj) {
    ids.emplace_back(obj);
}

ids.h:

#pragma once

#include <vector>
#include "wx/wx.h"

struct Object {
    wxObject* obj;
    const char* name;
    int id;
};

Object& search(const char*);

Object& search(int);

void add(Object&);

extern std::vector<Object> ids;
extern int maxid = 0;

Solution

  • The line

    extern int maxid = 0;

    in the file ids.h is a definition, because it also initializes the variable. Instead, it should only contain a declaration:

    extern int maxid;

    The definition should be in a source file (.cpp), not a header file (.h). Header files should only contain declarations of variables, not definitions. Otherwise, you will violate the one definition rule if you include the header file more than once, or if you already have a definition in a source file.

    In your case, you already have a definition of the variable in the file Tab.cpp. The line int maxid; is a definition, because it is not using the extern keyword. If you want to initialize the variable, you should do it in that file.