C++ Header File and Linker Errors [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm getting stranger error when I compile my code. I guess the header files aren't being properly linked because every single one of those variables that are erroring have been specified in 'variables.h' which I properly #include. Strangely enough, if I comment ou the areas in which the variables are used in main.cpp, a whole other slew of errors pop up of the same variables in another file readfile.cpp. Below is the error output, as well as my code for main.cpp and variables.h. Any ideas?
g++ -c main.cpp
g++ -c readfile.cpp
g++ -c Objects.cpp
g++ -o raytracer main.o readfile.o Objects.o
Undefined symbols for architecture x86_64:
"_depth", referenced from:
init() in main.o
readFile(char const*)in readfile.o
"_diffuse", referenced from:
readFile(char const*)in readfile.o
"_emission", referenced from:
readFile(char const*)in readfile.o
"_filename", referenced from:
init() in main.o
"_fov", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_height", referenced from:
init() in main.o
readFile(char const*)in readfile.o
"_lookatx", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_lookaty", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_lookatz", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_lookfromx", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_lookfromy", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_lookfromz", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_maxvertnorms", referenced from:
init() in main.o
readFile(char const*)in readfile.o
"_maxverts", referenced from:
init() in main.o
readFile(char const*)in readfile.o
"_shininess", referenced from:
readFile(char const*)in readfile.o
"_specular", referenced from:
readFile(char const*)in readfile.o
"_spherecount", referenced from:
init() in main.o
"_spheres", referenced from:
readFile(char const*)in readfile.o
"_triangles", referenced from:
readFile(char const*)in readfile.o
"_tricount", referenced from:
init() in main.o
"_trinormals", referenced from:
readFile(char const*)in readfile.o
"_trinormcount", referenced from:
init() in main.o
"_upx", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_upy", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_upz", referenced from:
init() in main.o
initCamera(float*)in readfile.o
"_vertexcount", referenced from:
init() in main.o
"_vertexnormcount", referenced from:
init() in main.o
"_vertices", referenced from:
readFile(char const*)in readfile.o
"_vertnormals", referenced from:
readFile(char const*)in readfile.o
"_width", referenced from:
init() in main.o
readFile(char const*)in readfile.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Below is variables.h..
#include "vertexnormal.h"
#include "sphere.h"
#include "tri.h"
#include "trinormal.h"
#include "vec.h"
#include <string>
#include <vector>
using namespace std;
// width and height specify image size
extern float width;
extern float height;
// maximum depth for a ray (level of recursion)
extern int depth;
// the output file to which the image should be written
extern string filename;
// camera specifiations (should i put in a struct?)
extern float lookfromx;
extern float lookfromy;
extern float lookfromz;
extern float lookatx;
extern float lookaty;
extern float lookatz;
extern float upx;
extern float upy;
extern float upz;
extern float fov;
//***************************//
// Geometry Specifications //
//***************************//
// specifies the number of vertrices for tri specifications
extern int maxverts;
// specifies the number of vertices with normals for tri specifications
extern int maxvertnorms;
// pile of inputted vertices
// might need to #include glm file
extern vector<vec> vertices;
// pile of inputted vertices with specified normals
extern vector<vertexNormal> vertnormals;
// pile of inputted spheres
extern vector<sphere> spheres;
// pile of inputted triangles
extern vector<tri> triangles;
// pile of inputted triangles using vertices with specified normals
extern vector<triNormal> trinormals;
extern int vertexcount;
extern int vertexnormcount;
extern int spherecount;
extern int tricount;
extern int trinormcount;
//**************************//
// Materials Specifiations //
//**************************//
extern float diffuse[3];
extern float specular[3];
extern float shininess;
extern float emission[3];
And here is my main.cpp,
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "Objects.h"
using namespace std;
#include "readfile.h"
#include "variables.h"
void init() {
cout << "Reading in scene file... \n";
cout << "Image size has been set to a " << width << " x " << height << " output. /n";
cout << "The maximum recursion depth has been set to " << depth << ". \n";
cout << "The image will be output to " << filename << ".png. \n";
cout << "The camera has been instantiated with the following properties: \n";
cout << "\t POSITION: (" << lookfromx << ", " << lookfromy << ", " << lookfromz << ") \n";
cout << "\t DIRECTION: (" << lookatx << ", " << lookaty << ", " << lookatz << ") \n";
cout << "\t UP: (" << upx << ", " << upy << ", " << upz << ") \n";
cout << "\t FIELD OF VIEW: " << fov << " \n";
cout << "An amount of " << vertexcount << " vertices has been specified with a maximum of " << maxverts << " allowed. \n";
cout << "An amount of " << vertexnormcount << " vertices with normals has been specified with a maximum of " << maxvertnorms << " allowed. \n";
cout << "An amount of " << spherecount << " spheres have been specified. \n";
cout << "An amount of " << tricount << " triangles have been specified. \n";
cout << "An amount of " << trinormcount << " triangles with calculated vertex normals have been specified. \n";
}
int main (int argc, char * argv[]) {
readFile(argv[1]);
init();
return 0;
}

Try this:
Open up your variables.h header file.
Copy ALL of the extern variable declarations.
Open up your main.cpp file.
Paste all your declarations copied from (2).
In the same main.cpp remove the keyword extern from each declaration.
Save all your files.
Lookup how extern works. Something tells me you missed that in your studies.
Ok, this has been covered in SO what, a few thousand times, but for the OP:
Declaring the Existence of a Variable
// DECLARE myvar, an int variable. no storage has been set aside
// this is simply telling the compiler this thing exists.. somewhere.
extern int myvar;
Defining The Existence of a Variable
// DEFINE myvar, an int variable. storage *is* set aside here.
// only ONE of these, by this name, can be in your global
// namespace in your program.
int myvar = 0;
Traditionally, extern declarations are in headers, but definitions are always in c/cpp files. There must be a matching definition for any extern-declared variable that is used in your program.
How this fits with your situation
All of your variables were declared in variables.h, but the were never defined anyway. By telling you to copy/paste all those declarations into a source file (any will do; I chose main.cpp because it was already in your project), and then removing the extern keyword in that source file (not the header), you were essentially defining where they all officially existed. Now all those references to extern'ed variables in your other source files finally have something to hook up to at link time.
Sidebar
In the c/cpp file where your variables are being defined, make sure you initialize them to proper values. This is the one and only place you can do it. you can NOT do it on any extern declaration. It can only be done on a definition.
Header File
extern int myvar; // note: no initial value.
Source File
int myvar = 0; // note: initialized to zero (0)
I hope that made at least a little sense.

extern float lookfromx;
extern float lookfromy;
extern float lookfromz;
extern float lookatx;
extern float lookaty;
extern float lookatz;
These are simply declarations. You need to define these variables somewhere in the program (in variables.cpp, for example). To make these definitions you can either
remove the extern keyword
add an initialiizer ( = value; )

Your variable.h file simply makes your variables portable across other files in the global scope, but they still need to be declared. Make sure to declare the actual variables in your main file(normal method of initialization).
The extern keyword declares a variable or function and specifies that it has external linkage (its name is visible from files other than the one in which it's defined). When modifying a variable, extern specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends). The variable or function may be defined in another source file, or later in the same file. Declarations of variables and functions at file scope are external by default.
Read more on the extern keyword

Related

Error message appearing on compiling g++ [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 4 years ago.
So for class we are learning about OOP in C++, and I built my class but every time I try to compile it I get this error message:
Undefined symbols for architecture x86_64:
"Player::set_assits(int)", referenced from:
_main in playerDataBase-666bbb.o
"Player::set_last_name(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
_main in playerDataBase-666bbb.o
"Player::set_team_name(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
_main in playerDataBase-666bbb.o
"Player::set_first_name(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
_main in playerDataBase-666bbb.o
"Player::set_year_of_birth(int)", referenced from:
_main in playerDataBase-666bbb.o
"Player::set_goals(int)", referenced from:
_main in playerDataBase-666bbb.o
"Player::Player()", referenced from:
_main in playerDataBase-666bbb.o
"Player::~Player()", referenced from:
_main in playerDataBase-666bbb.o
ld: symbol(s) not found for architecture x86_64
I can't understand why this happens, I have tried to run this by compiling separate .h, and .cpp files as well as by putting the class, and main function inside of the same .cpp file. Any help would be appreciated as well here is my code.
#include <iostream>
#include <string>
using namespace std;
class Player{
public:
Player();
~Player();
// accessors and mutators
void set_first_name(string in_first_name);
string first_name();
void set_last_name(string in_last_name);
string last_name();
void set_team_name(string in_team_name);
string team_name();
void set_year_of_birth(int in_year_of_birth);
int year_of_birth;
void set_goals(int in_goals);
int goals;
void set_assits(int in_assists);
int assists;
//methods
void display();
private:
string first_name_;
string last_name_;
string team_name_;
int year_of_birth_;
int goals_;
int assits_;
};
void Player::display(){
cout << first_name_ << last_name_ << endl;
}
int main(){
Player player;
player.set_first_name("John");
player.set_last_name("Tedesco");
player.set_team_name("Blyth Warriors");
player.set_year_of_birth(2002);
player.set_goals(2);
player.set_assits(7);
player.display();
}
Thanks for any help and sorry again for messy / poor code.
Thanks,
John
None of these methods are defined, only declared:
Player();
~Player();
// accessors and mutators
void set_first_name(string in_first_name);
string first_name();
void set_last_name(string in_last_name);
string last_name();
void set_team_name(string in_team_name);
string team_name();
void set_year_of_birth(int in_year_of_birth);
void set_goals(int in_goals);
void set_assits(int in_assists);
You need to provide reasonable definitions for these methods. Right now, you tell the compiler you will provide a definition for each of these methods, and never do. For default constructors, you may use Player() = default;, if you want the compiler to generate a constructor.
For example, to define the first_name property, you may do:
void Player::set_first_name(const string& in_first_name)
{
first_name_ = in_first_name;
}
const string& first_name() const
{
return first_name_;
}
Please note I've changed this to take value by constant reference, and return a value by constant reference, rather than by value, for efficiency reasons.
You declared all those fancy methods, e.g:
void set_first_name(string in_first_name);
string first_name();
But you never defined them!
Implement them, and it will work, e.g:
void set_first_name(string in_first_name) {
first_name_ = in_first_name;
}
string first_name() {
return first_name_;
}

Program keeps on giving such LNK errors

header.h
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
using namespace std;
//vector <Account> bankAccounts; this is taken out.
extern vector <Account> bankAccounts; //edited
struct Account {
int accountNumber;
string lastName;
string firstName;
double accountbalance;
};
void menu(int*);
void makeAccount(vector <Account>&);
cpp
#include "Header.h"
void menu(int*);
void makeAccount(vector <Account>&);
vector <Account> bankAccounts; //edited
int main() {
int input = 0;
int *inputPtr = &input;
menu(inputPtr);
switch (input) {
case 1:
makeAccount(bankAccounts);
}
}
another cpp
#include "Header.h"
vector <Account> bankAccounts; edited;
void menu(int *inputPtr) {
int select = 0;
cout << "Welcome to MadeUp Banking. Select options below: \n";
cout << "\t 1. Make new account. \n";
cout << "\t 2. Display to an account. \n";
cout << "\t 3. Deposit to an account. \n";
cout << "\t 4. Withdraw from an account. \n";
cout << "\t 5. Print account. \n";
cout << "\t 6. Delete an account. \n";
cout << "\t 7. Quit. \n";
cout << "Selection: ";
cin >> select;
*inputPtr = select;
}
void makeAccount(vector <Account> bankAccounts) {
//edited vector <Account> bankAccounts within makeAccount()
return;
}
When program is ran, the error gives:
main_file.obj : error LNK2005: "class std::vector > bankAccounts" (?bankAccounts##3V?$vector#UAccount##V?$allocator#UAccount###std###std##A) already defined in function_file.obj
1>main_file.obj : error LNK2019: unresolved external symbol "void __cdecl makeAccount(class std::vector > &)" (?makeAccount##YAXAAV?$vector#UAccount##V?$allocator#UAccount###std###std###Z) referenced in function _main
How do I go about fixing this error?
Sorry I'm a rookie coder, if more details are needed, then please tell me and I will edit accordingly. Thank you for the help in advance.
1. bankAccounts already defined in function_file.obj.
You should define bankAccounts in your cpp file. Because if you define it in header file, when you include your header in multiple cpp files, there would be multiple definition of backAccounts.
If you needs it in multiple cpp files, use extern to declare(not define) it in your header file:
extern vector <Account> bankAccounts;
And in one of your cpp file, define it as:
vector <Account> bankAccounts;
2. unresolved external symbol void makeAccount()
Definition of makeAccount() should be like:
void makeAccount(vector <Account>&)
{
// do something
}
While you are defining it as void makeAccount(vector<Account>). Please notice the difference. In your declaration, parameter is reference to a vector, while in your definition, parameter is vector object.
The error message of the first error, which can be abridged to:
main_file.obj : error LNK2005: std::vector<Account> bankAccounts already defined in function_file.obj
The reason for this error is that included files are copy-pasted in place of #include. That way, the std::vector<Account> bankAccounts is defined in both files (and they are, completely separate objects!), so the linker complains because of the multiple-definitions.
To solve this, in the header file, declare the global variable as extern std::vector<Account> bankAccounts, and then define it, in one of the .cpp files as std::vector<Account> bankAccounts. extern, only declares that there will be such a variable defined, at some point, and since you will be defining a global variable once, the linker won't see multiple definitions of said variable.
The second error is just like it sounds: you declared (and tried to call a function with signature void makeAccount(vector <Account>&);, however, you defined a function with signature void makeAccount();, leaving the function void makeAccount(vector <Account>&); undefined. Fix the definition of a function to include the parameter, present in its declarations:
void makeAccount(vector <Account>&) {
return;
}
Unrelated to your issues, but I felt that I should mention several more things:
Don't use using namespace std;, especially in the header files, it is considered a bad practice.
How is your code even reaching the linker stage? It shouldn't even compile, because Account is declared after the void makeAccount(vector <Account>&);, and at the point of such function declaration - struct Account is not known to the compiler.

.txt function not linking to main function [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I am making a program with a list of baby names but I've decided to make a seperate function to open the file, this is what I have got so far.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void open_file(ifstream& in, char fileName[]);
void find_name(ifstream& in, string name, int numNames);
int main() {
const int NUMNAMES = 1000;
ifstream inStream;
char fileName[30];
string name;
cout << "Enter the name of the file that contains the names: " << endl;
open_file(inStream, fileName);
cout << "Enter the name to search for (capitalize first letter): " << endl;
cin >> name;
find_name(inStream, name, NUMNAMES);
inStream.close();
}
void open_file(ifstream& ) {
string line;
ifstream myfile ("babyNames.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
}
myfile.close();
}
else cout << "I/O failure opening file babyNames";
}
Does anyone know why I am getting so many error messages:
Undefined symbols for architecture x86_64:
"find_name(std::__1::basic_ifstream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int)", referenced from:
_main in Untitled-1b6d2e.o
"open_file(std::__1::basic_ifstream<char, std::__1::char_traits<char> >&, char*)", referenced from:
_main in Untitled-1b6d2e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Does anyone know what I am doing wrong, I feel like it is relatively close I'm just fairly new to streams in c++.
The shown code declares and calls the following functions:
void open_file(ifstream& in, char fileName[]);
void find_name(ifstream& in, string name, int numNames);
Unfortunately, the shown code does not define any of these two functions, and the two linking errors are the result of that.
The shown code does define some function that's also called open_file(), but it's a completely different function because it takes different parameters. The shown code does not define any function called find_name().
You cannot simply declare a function like:
void open_file(ifstream& in, char fileName[]);
And then expect the code for this function to automatically appear somewhere. You have to define, and write the contents of this function. The parameters in this function, when you define it, must be the same as what you declared here.

Undefined Internal Linkage and Undefined Symbols Error

I tried compiling a simple program on Xcode and got the following messages:
function<anonymous namespace>::Initialize' has internal linkage but is not defined
function<anonymous namespace>::HandleBadInput' has internal linkage but is not defined
Undefined symbols for architecture x86_64:
"(anonymous namespace)::Initialize()", referenced from:
_main in main.o
"(anonymous namespace)::HandleBadInput()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The header file looks like this:
#ifndef WJKErrorHandling
#define WJKErrorHandling
namespace WJKErrorHandling{
void Initialize(void);
int HandleBadInput(void);
}
#endif // defined(WJKErrorHandling)
the implementation file looks like this:
#include <iostream>
#include "WJKErrorHandling.h"
namespace WJKErrorHandling{
void Initialize(void){
std::cin.exceptions(std::cin.failbit);
}
int HandleBadInput(void){
std::cerr << "Input Error: wrong type?\n";
std::cin.clear();
char BadInput[5];
std::cin >> BadInput;
return 1;
}
}
and main.cpp looks like this:
#include <iostream>
#include "WJKErrorHandling.h"
void Prompt (void){
//Prompts the user to begin entering numbers
std::cout << "Begin entering numbers: \n";
}
float GetNumber (void){
std::cout << "Number: \n";
float Number;
std::cin >> Number;
return Number;
}
std::string GetString (void){
std::cout << "String: \n";
std::string String;
std::cin >> String;
return String;
}
int main()
{
Prompt();
WJKErrorHandling::Initialize();
int ReturnCode = 0;
try{
float Number = GetNumber();
std::cout << Number;
std::string String = GetString();
std::cout << String;
std::cout << "SUCCESS!!!!\n";
}
catch(...){
ReturnCode = WJKErrorHandling::HandleBadInput();
}
return ReturnCode;
}
I've tried finding an answer so far, but I haven't understood any of the posts that I've found. I'm new with C++, so any help would be greatly appreciated!
Your #define Guard is causing name lookup issue.
change to below style should fix the issue:
#ifndef WJK_ERROR_HANDLING_H
#define WJK_ERROR_HANDLING_H
You could also use the non-standard but more idiomatic #pragma once, according to its wikipedia page it is supported by all major compilers.
Since many compilers have optimizations to identify include guards, there is no speed advantage between the two. For myself I see the following advantages of #pragma once:
It has only one meaning (whereas defines serve different purposes) and will not clash with other things (e.g. a namespace as in your case).
It is little to type and simple to remember.
You cannot have errors due to a typo (WJKERRORHANDLNG_H, ups and I is missing), because you started the header as a copy of another and forgot to change the include guard, which gives you rather nasty bughunting sessions.
This turns out to be a bad include guard:
#ifndef WJKErrorHandling
#define WJKErrorHandling
because you later try to use WJKErrorHandling as a namespace, but the macro makes it go away.
Change your include guard to something like:
#ifndef WJKERRORHANDLING_H
#define WJKERRORHANDLING_H
which is probably more idiomatic and less likely to conflict with something.

Undefined symbols for architecture, tried i386 and other ,,,

just wanted to start some C++ and created these simple class:
Ellipsoid.h
#ifndef __Ellipsoid__Ellipsoid__
#define __Ellipsoid__Ellipsoid__
#include <iostream>
#include <cassert>
class Ellipsoid {
private:
double axisA;
double flatteningF;
public:
Ellipsoid() {};
Ellipsoid(double aIn, double fIn);
double getAxisA();
double getFlatteningF();
};
#endif /* defined(__Ellipsoid__Ellipsoid__) */
Ellipsoid.cpp
#include "Ellipsoid.h"
Ellipsoid::Ellipsoid (double aIn, double fIn) : axisA(aIn), flatteningF(fIn) {};
int main() {
std::cout << "bla";
Ellipsoid el = Ellipsoid(44.3, 32);
double test = el.getAxisA();
return 0;
}
as you can see nothing special here. i'm using xcode on osx10.8.
But when i run the programm i come to this error:
Undefined symbols for architecture x86_64:
"Ellipsoid::getAxisA()", referenced from:
_main in Ellipsoid.o
ld: symbol(s) not found for architecture x86_64
and i really can't figure out whats wrong. tried to set the architecture to 32 bit but this won't work neither
The definition of the Ellipsoid::getAxisA() function is missing. You must define somewhere. Right now you only have a declaration, not a definition. The definition could look something like this:
double Ellipsoid::getAxisA() { return axisA; }
And would live in Ellipsoid.cpp.