Pesky Link Errors - c++

I am using visual studio 2010 and believe I have a project settings issue. I have a header file that has some declarations in it:
definitions.h
#include <string>
struct myStruct
{
std::string x[4];
std::string y[8];
};
void InitializeStructData();
extern myStruct data[12];
and the cpp file initializes my structure:
definitions.cpp
#include "definitions.h"
#include <string>
mySturct data[12];
void InitializeStructData()
{
data[0].x[0] = "a";
data[0].x[1] = "b";
....
data[0].y[0] = "a";
....
....
data[11].y[7] = "done initializing"';
}
and I have a form that has some buttons and things whose text I populate from the arrays depending on different circumstances:
myForm.cpp
#include "definitions.h"
...
//form initialization
As soon as I have two #include "definitions.h" statements I get link errors:
Error 1 error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * Definitions"
Error 2 error LNK1169: one or more multiply defined symbols found

Your question is missing the important part.
You have a std::string* Definitions in a header, that you forgot to use extern with.

Do you have your code (.h file) inside:
#ifndef DEFINITIONS_H
#define DEFINITIONS_H
#endif
to help prevent you from defining it multiple times, if you have it included in multiple places?

Related

C++ LNK2005 error related to enum

I am getting LNK error 2005 due to the use of enum in header file. I am not sure what is wrong with it though. Is enum usually included in the header file?
Here is my code. I have 4 files: board.h, board.cpp, Solitaire.h, Solitaire.cpp.
board.h:
#ifndef BOARD_H__
#define BOARD_H__
#include <iostream>
using namespace std;
const int NUM_ROWS = 6;
const int NUM_COLS = 6;
enum PieceType {
HasPiece, NoPiece, Invalid
};
PieceType board_data[NUM_ROWS][NUM_COLS];
#endif
board.cpp:
#include "board.h"
Solitaire.h
#ifndef Solitaire_h__
#define Solitaire_h__
#include "board.h"
#endif
Solitaire.cpp
#include "Solitaire.h"
int main() {
}
The error I get is
Error LNK2005 "enum PieceType (* board_data)[6]"
(?board_data##3PAY05W4PieceType##A) already defined in board.obj
Thank you!
The problem has to do with including definitions in headers. This line
PieceType board_data[NUM_ROWS][NUM_COLS];
defines a new array board_data in each translation unit from which the header is included. To fix this issue, declare the array external, i.e.
extern PieceType board_data[NUM_ROWS][NUM_COLS];
After that, define the array in one of your CPP files.
Note: This problem is not about enum - you would get the same error with any other type.

Why is my global variable causing problems?

I've been reading about global variables for an hour now and I can't get mine to work. I have two vectors of custom classes, Airport and Flight, which are defined in their respective header files. Then I declare the extern vectors in the Globals.h header which is included in main.cpp. If I leave the code as is, I get a "unresolved external symbol" error for both of the vectors:
error LNK2001: unresolved external symbol "class std::vector<class Airport,class std::allocator<class Airport> > airports" (?airports##3V?$vector#VAirport##V?$allocator#VAirport###std###std##A)
error LNK2001: unresolved external symbol "class std::vector<class Flight,class std::allocator<class Flight> > flights" (?flights##3V?$vector#VFlight##V?$allocator#VFlight###std###std##A)
If, instead, I forward declare (like I've been lead to believe is how it should be done) by putting
vector<Airport> airports;
vector<Flight> flights;
in front of main(), then I get these errors:
error C2371: 'airports' : redefinition; different basic types
error C2371: 'flights' : redefinition; different basic types
There's also errors given about allocators in vectors, and how one vector is not equal to the other vector. However, I cannot create a vector by typing vector> airport, which is what is suggested. This is mirrored by vector.
The code in my project is below. Any help would be appreciated.
main.cpp (simplified):
#include "stdafx.h"
#include "Globals.h"
using namespace std;
int main(){
airports = readInAirports();//returns a vector<Airport>
flights = readInFlights();//returns a vector<Flight>
}
Airport.h: (Flight.h is similar)
#ifndef AIRPORT_H
#define AIRPORT_H
#include <vector>
#include <string>
using namespace std;
class Airport{
public:
Airport(string c, string n, int dt, int cc)
:code(c), name(n),
departureTax(dt),connectionTime(cc)
{}
string toLine();
string getCode();
string getName();
int getDepTax();
int getConnTime();
private:
string code, name;
int departureTax, connectionTime;
};
#endif
Globals.h:
#ifndef GLOBALS_H
#define GLOBALS_H
#include <vector>
#include <string>
#include <math.h>
#include "Airport.h"
#include "Flight.h"
extern vector<Airport> airports;
extern vector<Flight> flights;
#endif
extern vector<Airport> airports;
This is a declaration of airports. It says "Somewhere in the program is a global variable called airports of type vector<Airport>".
vector<Airport> airports;
This is a definition of airports. It creates a global variable called airports of type vector<Airport>. You cannot have two global variables with the same name, even if they are in different files.
You should know that #include effectively copy-pastes the whole contents of the included file into this file. So if you put a definition in a header file, and include that header file in two different source files, then you have two definitions.
The solution is to put the declarations in the header file (with extern) and the definitions in one source file.
Because you have't defined them. You only declared them (extern only declares).
You need to add the definitions for both airports and flights in a .cpp file, like so:
vector<Airport> airports;
vector<Flight> flights;
Furthermore, vector<Airport> airports; is not a forward declaration, it's a definition. To forward declare variables you need to use the extern keyword.

Re-definitions of functions while including files in C++ (error LNK2005)

I'm new to C++ and I have a basic doubt.
I'm creating a french verb conjugating application.
I have two files, a Conjugator.cpp file and an ErVerbs.cpp file.
I want to keep the bulk of my functions in the ErVerbs source file and use the conjugator
file to use these functions.
Here are a few code snippets:
Conjugator.cpp
#include <iostream>
#include <string>
#include "Variables.h"
#include "ErVerbs.cpp"
#include "IrVerbs.cpp"
#include "ReVerbs.cpp"
using namespace std;
void check()
{
if (verb.substr(len - 2, len) == "er")
erVerbs();
else if (verb.substr(len - 2, len) == "ir")
irVerbs();
else if (verb.substr(len - 2, len) == "re")
reVerbs();
}
int main()
{
cout << "Enter verb : ";
getline(cin, verb);
cout << "Enter tense : ";
getline(cin, tense);
len = verb.length();
check();
}
ErVerbs.cpp
#include <iostream>
#include <string>
using namespace std;
void erVerbs()
{
cout << "er Verb"; cin.get();
}
Similarly, I have three other such .cpp source files with similar functions.
When I build the program, I get an error that each of the methods I'm using has been defined
already.
1>ErVerbs.obj : error LNK2005: "void __cdecl erVerbs(void)" (?erVerbs##YAXXZ) already defined in Conjugator.obj
1>ErVerbs.obj : error LNK2005: "void __cdecl erVerbs(void)" (?erVerbs##$$FYAXXZ) already defined in Conjugator.obj
1>IrVerbs.obj : error LNK2005: "void __cdecl irVerbs(void)" (?irVerbs##YAXXZ) already defined in Conjugator.obj
1>IrVerbs.obj : error LNK2005: "void __cdecl irVerbs(void)" (?irVerbs##$$FYAXXZ) already defined in Conjugator.obj
1>ReVerbs.obj : error LNK2005: "void __cdecl reVerbs(void)" (?reVerbs##YAXXZ) already defined in Conjugator.obj
1>ReVerbs.obj : error LNK2005: "void __cdecl reVerbs(void)" (?reVerbs##$$FYAXXZ) already defined in Conjugator.obj
I'd be extremely grateful if someone could tell me how to save functions in separate source files and #include them in one source files and use their functions without re-definition errors.
Dont:
#include "ErVerbs.cpp"
in Conjugator.cpp, this is what causing your linker errors. By including your cpp files like that you redefine this function again.
You should create ErVerbs.h file and put in it declaration for your function:
#if !defined(ER_VERBS_H)
#define(ER_VERBS_H)
void erVerbs();
#endif
and in Conjugator.cpp, include #include "ErVerbs.h", and the same for other your functions.
You should never include *.cpp files. Delete following
#include "ErVerbs.cpp"
#include "IrVerbs.cpp"
#include "ReVerbs.cpp"
Create erVerbs.h with following content:
void erVerbs();
and include it in Conjugator.cpp
#include "ErVerbs.h"
As you included modules
#include "ErVerbs.cpp"
#include "IrVerbs.cpp"
#include "ReVerbs.cpp"
in module Conjugator.cpp then all four modules contain definitions of the functions and the compiler says about this.
You have to declare the functions in some header file and include it in all modules that uses these functions while their definitions to keep in one module (or among several modules) that will not be included in any other module.
You're #including a .cpp file from another .cpp file, so the function definition will exist in two places.
What you probably want to do is create a Conjugator.h header file, declaring (but not defining) the function, and include that instead.
Also look up header guards (or #pragma once) while you're at it, if you're not aware of how to prevent multiple declarations in .h files.

LNK2005: " already defined error

I am trying to use a global variable from separated .cpp files. I have got an init.h file as:
//init.h
#ifndef init
#define init
int a = 3;
#endif
I have got an init.cpp file as:
//init.cpp
#include init.h
Then finally my main.cpp file is:
//main.cpp
#include "init.h"
int main(void)
{
while(1)
{
}
}
After this, I get the error:
1>init.obj : error LNK2005: "int a" (?a##3HA) already defined in main.obj
1> ..deneme.exe : fatal error LNK1169: one or more multiply defined symbols found
Why my #infdef control does not solve this problem?. I also tried using #pragma once but I got same error. What is wrong with my code?
You need to mark your variable as extern and define it only once in an implementation file.
As the code is now, you're breaking the one definition rule. The include guards don't help in this case, since all translation units that include that header re-define the variable.
What you actually need:
//init.h
#ifndef init
#define init
extern int a;
#endif
and the definition:
//init.cpp
#include "init.h"
int a = 3;
Also, think twice before using globals. What is it that you're actually trying to achieve?

Multiple Definition (LNK2005) errors

I recently tried to create a global header file which would have all definitions of error codes (i.e. NO_ERROR, SDL_SCREEN_FLIP_ERROR, etc.) these would just be integers which I would define here.
I included these in both of my .cpp files, however I am getting an error where it is stated that I am defining then twice.
globals.h:
#pragma once
// error related globals
int SCREEN_LOAD_ERROR = 1;
int NO_ERROR = 0;
main.cpp:
#include "globals.h"
#include "cTile.h"
/* rest of the code */
cTile.h:
#pragma once
#include "globals.h"
class cTile {
};
It is complaining that SCREEN_LOAD_ERROR and NO_ERROR are defined twice, but as far as I know #pragma once should prevent this (I also tried #ifndef, but this also did not work).
compiler output:
1>main.obj : error LNK2005: "int SCREEN_LOAD_ERROR" (?SCREEN_LOAD_ERROR##3HA) already defined in cTile.obj
1>main.obj : error LNK2005: "int NO_ERROR" (?NO_ERROR##3HA) already defined in cTile.obj
Am I missing something?
Do not declare variables inside your header file.
When you declare a variable in header file a copy of the variable gets created in each translation unit where you include the header file.
Solution is:
Declare them extern inside one of your header file and define them in exactly one of your cpp file.
globals.h:
extern int SCREEN_LOAD_ERROR;
extern int NO_ERROR;
globals.cpp:
#include "globals.h"
int SCREEN_LOAD_ERROR = 0;
int NO_ERROR = 0;
main.cpp:
#include "globals.h"
cTile.h:
#include "globals.h"
You could simply use an enum:
globals.h:
enum
{
SCREEN_LOAD_ERROR = 1,
NO_ERROR = 0,
// ...
}
using #ifndef works fine.(Although it works, this is not best practice). try like this:
globals.h
#ifndef GLOBALS
#define GLOBALS
int SCREEN_LOAD_ERROR = 1;
int NO_ERROR = 0;
#endif
cTile.h:
#include "globals.h"
class cTile {
};
main.cpp:
#include "globals.h"
#include "cTile.h"
/* rest of the code */