0

I searched a lot but could not find the problem. I build a simple Snake Game. I was using a Makefile to build and Debug. But I switched to VS-Code. Now I am only getting Problems, that I did not have with the Makefile.

Do I need to change something in Vs-Code?

These are the problems:

Starting build...
/usr/bin/g++ -fdiagnostics-color=always -g -o /home/kali/path/snakeMain /home/kali/path/*.cpp -lncurses
/usr/bin/ld: /tmp/ccCKG1t0.o:/home/kali/path/Snake.h:9: multiple definition of `gameOver'; /tmp/ccJxCKEW.o:/home/kali/path/Snake.h:9: first defined here
/usr/bin/ld: /tmp/ccCKG1t0.o:/home/kali/path/Snake.h:14: multiple definition of `headX'; /tmp/ccJxCKEW.o:/home/kali/path/Snake.h:14: first defined here
/usr/bin/ld: /tmp/ccCKG1t0.o:/home/kali/path/Snake.h:14: multiple definition of `headY'; /tmp/ccJxCKEW.o:/home/kali/path/Snake.h:14: first defined here
/usr/bin/ld: /tmp/ccCKG1t0.o:/home/kali/path/Snake.h:17: multiple definition of `tailX'; /tmp/ccJxCKEW.o:/home/kali/path/Snake.h:17: first defined here
/usr/bin/ld: /tmp/ccCKG1t0.o:/home/kali/path/Snake.h:17: multiple definition of `tailY'; /tmp/ccJxCKEW.o:/home/kali/path/Snake.h:17: first defined here
/usr/bin/ld: /tmp/ccCKG1t0.o:/home/kali/path/Snake.h:18: multiple definition of `tailLength'; /tmp/ccJxCKEW.o:/home/kali/path/Snake.h:18: first defined here
/usr/bin/ld: /tmp/ccCKG1t0.o:/home/kali/path/Snake.h:21: multiple definition of `current_dir'; /tmp/ccJxCKEW.o:/home/kali/path/Snake.h:21: first defined here
/usr/bin/ld: /tmp/ccCKG1t0.o:/home/kali/path/Snake.h:23: multiple definition of `key'; /tmp/ccJxCKEW.o:/home/kali/path/Snake.h:23: first defined here
collect2: error: ld returned 1 exit status

Build finished with error(s).

 *  The terminal process terminated with exit code: -1. 
 *  Terminal will be reused by tasks, press any key to close it. 

I am Using the latest Vs-Code in Linux. I installed it again today. I think the problem is wrong linking.

I dont know how to do it in vs-code and unfortunatly the Internet could not help me.

This is my Snake.cpp:

#include <iostream>
#include <ncurses.h>
#include <unistd.h>
#include "Snake.h"

// Setup
void initTerminal() {
}

void initSnake() {
}

// Draw
void drawPixel(int y, int x) {

}

void drawBorder() {
  // PRINT MAP
}

void drawSnake() {
}

// Logic
bool collidesWithBorder() {

}

bool collidesWithSelf() {  
}

void moveSnake() {
}

bool handleKey(int key) {
}

my snakeMain.cpp:

#include <iostream>
#include <ncurses.h>
#include <unistd.h>
#include "Snake.h"

int main() {
//-----here is only code and no #includes------/
return 0;
}

my Snake.h

// Copyright 2022
// Author: Darky

#ifndef SNAKE_H_
#define SNAKE_H_

//Golabal var
  // Used for the Loop
  bool gameOver;
  //field Dimensions
  const int f_width = 40;
  const int f_height = 40;
  // Coordinates for the Head of Snake
  int headX, headY;
  // Coordinates for the Tail, max Length (if we continue develop)
  // inital tailLenght (actual length is in drawSnake())
  int tailX[25], tailY[25];
  int tailLength = 0;
  // Direction param
  enum direction { STOP = 0, LEFT, RIGHT, UP, DOWN};
  direction current_dir;
  // input of the User
  int key;

// Functions
//  Initialize the Game
  void initTerminal();
  void initSnake();

// Draw the Game
  // Draw a Singel Pixel into Gamefield
  void drawPixel(int y, int x);
  // Draws the Gamefield
  void drawBorder();
  // Draw Snake with tail
  void drawSnake();

// Logic of the Game
  // Check if hit the border
  bool collidesWithBorder();
  // Check if collides with Snaketail
  bool collidesWithSelf();
  // set the direction of the snake
  void moveSnake();
  // pick input and transfer to direction
  bool handleKey(int key);

#endif // SNAKE_H_

my tasks.json:

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}",
                "${workspaceFolder}/*.cpp",
                "-lncurses"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
        }
    ],
    "version": "2.0.0"
}

and my settings.json:

{
    "files.associations": {
        "iostream": "cpp"
    }
}

Again, the game is working if I start it in the console and compile it with the makefile. But in Vs-Code I get the Problem as described above.

Thank you everybody for your time.

Darky
  • 11
  • 2
  • `gameOver` is a non-static variable, i.e. in every translation unit where you include `Snake.h` a different version of the variable is created and the linker won't allow you to merge the results of those compilations. If you really insist on using global variables you need to define them in a single translation unit and declare them as `extern` in the header. I recommend not using globals though... – fabian Jul 24 '22 at 14:25
  • Some dupes: [dupe1](https://stackoverflow.com/questions/11072244/c-multiple-definitions-of-a-variable), [dupe2](https://stackoverflow.com/questions/37578441/multiple-definitions-error-in-c), [dupe3](https://stackoverflow.com/questions/55238194/multiple-definition-error-on-variable-that-is-declared-and-defined-in-header-fil) and [dupe4](https://stackoverflow.com/questions/18914122/multiple-definitions-error-in-c-and-solution-to-solve-this-issue). Refer to a [HOW TO ASK](https://stackoverflow.com/help/how-to-ask) where the first step is *search and then research*. – Jason Jul 24 '22 at 14:43

1 Answers1

1

In your header file:

bool gameOver;

This header file gets #included into both of your .cpp files.

An #include is logically equivalent to physically inserting the contents of the header flie into .cpp file.

In this manner, both of your .cpp files define gameOver, and all the other variables defined in this header file.

This violates C++'s One Definition Rule: each object must be defined only once. This is the reason for your compilation failure.

You will need to move the definitions of all of your variables into one of your .cpp files, and use the extern keyword in the header file to declare all of these objects in your header file, that gets included into both .cpp files.

See your C++ textbook for more information and explanation of so-called "forward declarations", and the extern keyword.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Wow you all are really great. I thought my .json was the problem. Could you please also tell me how I can link multiple header and cpp files in Vs code? Thank you guys so much. Everything is working now. – Darky Jul 24 '22 at 14:38
  • Going to https://www.google.com and typing "link multiple files vscode" produces many very useful links. – Sam Varshavchik Jul 24 '22 at 15:23