0

So I have been trying to write a TicTacToe game on c++, I'm trying to learn header files. But I keep getting errors about multiple definitions. So I have three files (2 cpp files and 1 header). I'm still learning stuff, so pardon my messy code.

main.cpp

#include <iostream>
#include "game.h"
using namespace std;

    int main()
    {
        cout << "TicTacToe Game!" << endl;
        play();
        cout << "Wanna play again (y/n)? ";
        cin >> again;
        if(again == 'y') play();
        return 0;
    }

game.h

#ifndef GAME_H
#define GAME_H

char l[9];
char again;
bool over;
int winner;
void board();
void play();

#endif

game.cpp

#include <iostream>
#include "game.h"
using namespace std;

void board()
{
    cout << "\t\t\t" << "|" << "\t\t\t" << "|" << "\t\t\t" << endl;
    cout << "\t" << l[0] << "\t" << "|" << "\t" << l[1] << "\t" << "|" << "\t" << l[2] << "\t" << endl;
    cout << "\t\t\t" << "|" << "\t\t\t" << "|" << "\t\t\t" << endl;
    cout << "------------|------------------|---------------" << endl;
    cout << "\t\t\t" << "|" << "\t\t\t" << "|" << "\t\t\t" << endl;
    cout << "\t" << l[3] << "\t" << "|" << "\t" << l[4] << "\t" << "|" << "\t" << l[5] << "\t" << endl;
    cout << "\t\t\t" << "|" << "\t\t\t" << "|" << "\t\t\t" << endl;
    cout << "------------|------------------|---------------" << endl;
    cout << "\t\t\t" << "|" << "\t\t\t" << "|" << "\t\t\t" << endl;
    cout << "\t" << l[6] << "\t" << "|" << "\t" << l[7] << "\t" << "|" << "\t" << l[8] << "\t" << endl;
    cout << "\t\t\t" << "|" << "\t\t\t" << "|" << "\t\t\t" << endl;
}

void play()
{
    over = false;
    for(int i=0; i<9; i++) l[i] = '\t';
    board();
    while(over!=true)
    {
        int move;
        player1_move:
        cout << "Player 1 move (from 1 to 9): ";
        cin >> move;
        if(l[move-1] == 'X' | l[move-1] == 'O') goto player1_move;
        l[move-1] = 'X';
        board();
        if (l[0] == l[1] == l[2] | l[3] == l[4] == l[5] | l[6] == l[7] == l[8] | l[0] == l[3] == l[6] | l[1] == l[4] == l[7] | l[2] == l[5] == l[8] | l[0] == l[4] == l[8] | l[2] == l[4] == l[6])
        {
            over = true;
            winner = 1;
        }
        player2_move:
        cout << "Player 2 move (from 1 to 9): ";
        cin >> move;
        if(l[move-1] == 'X' | l[move-1] == 'O') goto player2_move;
        l[move-1] = 'O';
        board();
        if (l[0] == l[1] == l[2] | l[3] == l[4] == l[5] | l[6] == l[7] == l[8] | l[0] == l[3] == l[6] | l[1] == l[4] == l[7] | l[2] == l[5] == l[8] | l[0] == l[4] == l[8] | l[2] == l[4] == l[6])
        {
            over = true;
            winner = 2;
        }
    }
    cout << "The winner is Player " << winner << "!" << endl;
}

I keep getting errors about multiple definitions of l, again, over, and winner variables. My terminal error log is so messed up, so I tried an online c++ compiler and here is the error log.

/tmp/ccfv8AEX.o:(.bss+0x0): multiple definition of `l'
/tmp/ccjhOuGi.o:(.bss+0x0): first defined here
/tmp/ccfv8AEX.o:(.bss+0x9): multiple definition of `again'
/tmp/ccjhOuGi.o:(.bss+0x9): first defined here
/tmp/ccfv8AEX.o:(.bss+0xa): multiple definition of `over'
/tmp/ccjhOuGi.o:(.bss+0xa): first defined here
/tmp/ccfv8AEX.o:(.bss+0xc): multiple definition of `winner'
/tmp/ccjhOuGi.o:(.bss+0xc): first defined here
collect2: error: ld returned 1 exit status
Aziz AQ
  • 1
  • 1

2 Answers2

1

When you define variables like this,

#ifndef GAME_H
#define GAME_H

char l[9];
char again;
bool over;
int winner;
void board();
void play();

#endif

In a header file, these variables will be copied to every file which includes the header file.

To resolve this, mark them as inline.

#ifndef GAME_H
#define GAME_H

inline char l[9];
inline char again;
inline bool over;
inline int winner;
void board();
void play();

#endif

Notice that these errors are only for variables, and not for functions. This is because in the header file, you have the function declaration, not the definition.

D-RAJ
  • 3,263
  • 2
  • 6
  • 24
0

You need to do two things.

  1. Copy the variable definitions from your .h file into one of your .cpp files.

  2. Put "extern" in front of them in your .h file so it looks like:

    extern char l[9];

Here's what's going on. Each of your .cpp files defines variable l -- but it's not the SAME ONE. So the linker sees two copies and doesn't know which one to keep.

By defining them as extern, then both .cpp files knows you're just saying, "char l[9] exists somewhere. Don't worry about it." That fixes half the linker problem. But then you still need to actually declare them somewhere, which is why you then put:

char l[9];

Into ONE but not both .cpp.

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36