Thread: fatal error LNK1120: 2 unresolved externals

  1. #1
    Registered User
    Join Date
    Aug 2010
    Posts
    5

    Question fatal error LNK1120: 2 unresolved externals

    I have been working on these same errors for hours. There is no decent guide that I can seem to find that explains how to procedurally check code for what may or may not be causing these errors, and anything I do find that has these same error codes usually ends up being about some specific library file... I am using no additional libraries at all.. I am only using a student class that I have created, in its own .h and .cpp files. I am overriding the >> and << operators.. and cannot seem to get rid of these errors.

    1>Module 7 - Assignment 7.obj : error LNK2020: unresolved token (0A0002A8) "class Student * students" (?students@@3PAVStudent@@A)
    1>Module 7 - Assignment 7.obj : error LNK2001: unresolved external symbol "class Student * students" (?students@@3PAVStudent@@A)
    1>I:\College\~Summer 2010\10SS_INFO_1532_WW - C++ Programming II\Week 8 - Module 7\Module 7 - Assignment 7\Debug\Module 7 - Assignment 7.exe : fatal error LNK1120: 2 unresolved externals
    I am more than Happy to post my code if needed. All I need is a direction to look.. I'd happily peruse through hex data or anything if I can be directed to a guide that will instruct me on how to do so.. I am completely lost. No class I have attended teaches how to debug these errors..

    I am using Visual Basic 2008, using windows 7 64bit.

  2. #2
    Registered User
    Join Date
    Aug 2010
    Posts
    5
    There are a lot of views but no one answering... I really need assistance.. and I have already checked all of my resources, google, cplusplus.com, cprogramming.com articles, C++ faq lite, etc...

    I have started a new project, copied the code, pasted that, rebuilt the code.. rearranged items...

    If I comment out a line it will work, but commenting out any other lines will not make it work..

    Code:
    cin >> students[numGradesToGet];

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    So did you add students.cpp to your project, along with say main.cpp ?

    Did you check for spelling / capitalisation errors?
    Student != student
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Yes, post your code. Since it sounds like you are not using an IDE you will also need to manually compile your stedent cpp file into an object file, and then link everything into your exe. I would recommend getting an IDE to do this for you, or at the very least a makefile.

    Also I was a bit confused on your statement of using visual basic 2008, seeing as what you posted is surely not VB.

  5. #5
    Registered User
    Join Date
    Aug 2010
    Posts
    5
    Ok thank you for replying.. my code is quite large but I'll post it.

    I am using Visual Studio 2008, professional (provided by the college)


    Code:
    //Student.h the specification file for class Student
    
    #include <iostream>
    
    using namespace std;
    
    class Student{
    
    	
    friend istream & operator>> (istream&, Student &);
    //Function overrides the instream operator.
    //Intended to ease the input of student data
    
    friend ostream & operator<< (ostream&, const Student &);
    //Function overrides the outstream operator.
    //Intended to ease the output of student data
    	
    private:
    
    char name[46];
    //Student’s name: 45 characters, alpha-numeric
    
    char grade;
    //Student grade: Characters, A, B, C, D, & F
    
    float gpa;
    //Student GPA: floats
    
    
    public:
    
    void setName(std::string newName);
    //Function to set the name of the student
    //Postcondition: name = newName;
    
    std::string getName();
    //Function to get the name of the student
    //Postcondition: returns the name of the student
    //				as a string
    
    void setGrade(char newGrade);
    //Function to set the Grade of the student
    //Postcondition: grade = newGrade;
    
    char getGrade();
    //Function to get the grade of the student
    //Postcondition: returns the grade of the student
    //				as a character
    
    
    void setGpa(float newGpa);
    //Function to set the name of the student
    //Postcondition: gpa = newGpa;
    
    float getGpa();
    //Function to get the gpa of the student
    //Postcondition: returns the gpa of the student
    //				as a float
    
    
    
    
    Student();
    //Default Constructor
    //All variables are set to 0 or "" or ' '
    
    ~Student();
    //default destructor
    
    };
    Code:
    //Student.cpp The implementation file
    
    #include "stdafx.h"
    #include <String>
    //#include <iostream>
    #include "Student.h"
    
    
    //using namespace std;
    
    
    
    istream& operator>>(istream& cin2, Student &studentObject)
    {
    		char temp;
    
    		cin2 >> temp;
    
    			//studentObject.setGrade(temp);
    		return cin2;
    }
    
    ostream& operator<<(ostream& cout, const Student &studentObject)
    {
    
    	return cout;
    }
    
    
    
    void Student::setName(string newName)
    {
    	for (unsigned int i = 0; i < newName.length(); i++)
    	{
    		name[i] = newName.at(i);
    	}
    }
    
    string Student::getName()
    {
    	return name;
    }
    
    
    void Student::setGrade(char newGrade)
    {
    	grade = newGrade;
    	
    }
    
    char Student::getGrade()
    {
    	return grade;
    }
    
    
    void Student::setGpa(float newGpa)
    {
    	gpa = newGpa;
    
    }
    
    float Student::getGpa()
    {
    	return gpa;
    }
    
    
    
    Student::Student()
    {
    
    char name[46] = "";
     
    char grade = ' ';
    
    float gpa = 0.0;
    
    }
    
    
    Student::~Student(){}
    //default destructor
    Code:
    /*
    Module7-Assignment7.cpp : main project file.
    Written by Schuett, Hugh for Assignment 2, Module 2
    10SS_INFO_1532_WW - C++ Programming II, Metropolitan Community College
    Modified by Russell Dempsey, for Assignment 2, Module 2, MCC, JUNE 2010
    Modified by Russell Dempsey, for Assignment 6, Module 6, MCC, JULY 2010
    Modified by Russell Dempsey, for Assignment 7, Module 7, MCC, AUG 2010
    
    */
    
    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    #include <conio.h>
    #include <string>
    #include "Student.h"
    
    
    /*
    
    For this project you are going to take the last project, #6 (the grades program), and this time you are going to add operator overloading.  
    	Remember the programming example at the end of the chapter is a great example of this.
    Project Requirements:
    <!--[if !supportLists]-->1.     <!--[endif]-->A class object of this class will be all the information for one student.
    <!--[if !supportLists]-->2.     <!--[endif]-->You will have an array (4) of the objects, one element for each student.
    <!--[if !supportLists]-->3.     <!--[endif]-->You will overload the extraction operator (“>>”).  The overloaded operator will then 
    	perform all of the grade input for that individual.  The code in your main will look like this:  cin >> students[counter];  
    	Where students is the array of objects and counter is the subscript.
    <!--[if !supportLists]-->4.     <!--[endif]-->You will overload the insertion operator (“<<”).  The overloaded operator will then 
    	perform all of the grade output for that individual.  The code in your main will look like this:  cout << students[counter];  Where 
    	students is the array of objects and counter is the subscript.
    
    */
    
    Student students[];
    
    void gradeRecursion(int);
    void displayOutput();
    
    using namespace std;
    
    int main ()
    {
    	/*
    	name = new string[4];
    
    	//DEBUGGING
    	//cout << "\n\n " << &name << "\n\n";
    	//DEBUGGING
    
    	*name = "Freddie";
    	*(++name) = "Jane";
    	*(++name) = "Jonathan";
    	*(++name) = "Mary";
    
    	//DEBUGGING
    	//cout << "\n\n " << &name << "\n\n";
    	//DEBUGGING
    
    	name=name-3;
    	totalGPA = new double[4];
    	*/
    
    
    	Student students[4];
    	students[0].setName("Freddie");
    	students[1].setName("Jane");
    	students[2].setName("Jonathan");
    	students[3].setName("Mary");
    
    	
    	gradeRecursion(3);
    	//cin >> students[1];
    
    	displayOutput();  
    
    	cout << "\nPress any key to continue ..." << flush;
    	_getch();
    
    	/*
    	delete [] name;
    	delete [] totalGPA;
    	name  = 0;
    	totalGPA = 0;
    	*/
    
    	return 0;
    }
    
    void gradeRecursion(int numGradesToGet)
    {
    	
    	if (numGradesToGet >= 0)
    	{
    		
    		
    		//char grade;
    
    		cout << "Enter " << students[numGradesToGet].getName() << "'s Grades" << endl;
    
    		for ( int y=1; y<6; y++ )
    		{
    			cout << "Grade # " << students[numGradesToGet].getName() << "'s Letter Grade: ";
    			
    			cin >> students[numGradesToGet];
    
    			switch(students[numGradesToGet].getGrade())
    			{
    			case 'A': case 'a': students[numGradesToGet].setGpa(students[numGradesToGet].getGpa()+4);
    				break;
    			case 'B': case 'b': students[numGradesToGet].setGpa(students[numGradesToGet].getGpa()+3);
    				break;
    			case 'C': case 'c': students[numGradesToGet].setGpa(students[numGradesToGet].getGpa()+2);
    				break;
    			case 'D': case 'd': students[numGradesToGet].setGpa(students[numGradesToGet].getGpa()+1);
    				break;
    			case 'F': case 'f': students[numGradesToGet].setGpa(students[numGradesToGet].getGpa()+0);
    				break;
    			default: cout << "A Valid Letter Grade is A, B, C, D, or F " << endl;
    				y--;
    			}
    		}
    
    		students[numGradesToGet].setGpa(students[numGradesToGet].getGpa()/5);
    		
    		system("cls");
    
    		if (numGradesToGet > 0)
    		{
    			gradeRecursion(numGradesToGet-1);
    		}
    
    	}
    }
    
    void displayOutput()
    {
    	
    	cout << fixed << showpoint << setprecision(3);
    	cout << setw(30) << left << "Student" << right << "GPA\n " << endl;
    
    	for( int x=3; x>=0; x-- )
    	{
    		//cout << students[x];
    		//cout << setw(30) << left << name[x] << right << totalGPA[x]/5 << endl;
    	}
    }

  6. #6
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Ok, that makes it easier then. As Salem said, is student.cpp/h part of your project? If not, right click on your project in the solution explorer and add existing item. Then build your project.

  7. #7
    Registered User
    Join Date
    Aug 2010
    Posts
    5
    It's definitely part of the project

    see the attached screenshot.

    Everywhere I found other examples of LNK errors, people say 'its a library file this or that..' usually someone doing 3d, or windows gui stuff where they need to use additional libraries besides the STL..

    I am not doing any such thing so I have no idea why this error would come about besides the fact that microsoft and all it's software has a vendetta for me

  8. #8
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Remove the Student students[4]; from main, and remove Student students[]; globally. Set Student students[4]; globally.

    Code:
    Student students[4];
    
    void gradeRecursion(int);
    void displayOutput();
    
    using namespace std;
    
    int main ()
    {
    	/*
    	name = new string[4];
    
    	//DEBUGGING
    	//cout << "\n\n " << &name << "\n\n";
    	//DEBUGGING
    
    	*name = "Freddie";
    	*(++name) = "Jane";
    	*(++name) = "Jonathan";
    	*(++name) = "Mary";
    
    	//DEBUGGING
    	//cout << "\n\n " << &name << "\n\n";
    	//DEBUGGING
    
    	name=name-3;
    	totalGPA = new double[4];
    	*/
    
    
    	students[0].setName("Freddie");
    	students[1].setName("Jane");
    	students[2].setName("Jonathan");
    	students[3].setName("Mary");
    This is just to make your project immediately compile, you should consider passing in this parameter to your functions.

  9. #9
    Registered User
    Join Date
    Aug 2010
    Posts
    5
    Holy crap.. its working!! I will definitely add the constructor.. I usually try to change a little as possible till I get a working example and can then improve... it's running as we speak with just your change..

    how in the heck do I figure this out in the future?? How did you figure this out?




    Thank you!
    Last edited by SgtPooki; 08-07-2010 at 02:07 AM. Reason: To say thank you

  10. #10
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    #1. Consider making your "get" functions const as they do not modify the object they are being called on:
    Code:
    class Student{
    
        ...
    
        std::string getName() const;
        //Function to get the name of the student
        //Postcondition: returns the name of the student
        //				as a string
    
        ...
    
        char getGrade() const;
        //Function to get the grade of the student
        //Postcondition: returns the grade of the student
        //				as a character
    
        ...
    
        float getGpa() const;
        //Function to get the gpa of the student
        //Postcondition: returns the gpa of the student
        //				as a float
    
        ...
    };
    
    ...
    
    string Student::getName() const
    {
        return name;
    }
    
    
    ...
    
    char Student::getGrade() const
    {
        return grade;
    }
    
    ...
    
    float Student::getGpa() const
    {
        return gpa;
    }
    
    ...


    #2.
    Code:
    class Student{
    
    ...
    
    char name[46];
    //Student’s name: 45 characters, alpha-numeric
    
    char grade;
    //Student grade: Characters, A, B, C, D, & F
    
    float gpa;
    //Student GPA: floats
    
    ...
    
    };
    
    ...
    
    Student::Student()
    {
        char name[46] = "";
        char grade = ' ';
        float gpa = 0.0;
    }
    You should not be declaring those variables in the constructor as they are not the same as the ones your declared earlier (the class member variables).


    #3. Consider making the name member variable a real C++ string container/object and not a C-style string (null terminated char array). Then you can simplify things like this:
    Code:
    void Student::setName(string newName)
    {
        for (unsigned int i = 0; i < newName.length(); i++)
        {
            name[i] = newName.at(i);
        }
    }
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by SgtPooki View Post
    how in the heck do I figure this out in the future?? How did you figure this out?
    Look at the errors:
    1>Module 7 - Assignment 7.obj : error LNK2020: unresolved token (0A0002A8) "class Student * students" (?students@@3PAVStudent@@A)
    1>Module 7 - Assignment 7.obj : error LNK2001: unresolved external symbol "class Student * students" (?students@@3PAVStudent@@A)
    See the red? Familiar?
    Then find the code with students.

    Student students[];
    Student students[4];
    cout << "Enter " << students[numGradesToGet].getName() << "'s Grades" << endl;

    You are confusing the poor compiler.
    You've said there's an array of students globally (which has no size), so apparently the compiler assumes it's an external declaration (ie, the array exists in another source file). But it doesn't. So the linker throws a tantrum.

    Problem? You defined students locally in main and added some magic to fool the compiler.
    The best way to solve them is to read the error messages. If you don't understand them, post them here, and we can interpret them for you.
    Also, I'd bug your college to upgrade to VS2010.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Testpad for itoa()
    By frktons in forum C Programming
    Replies: 92
    Last Post: 07-19-2010, 03:05 PM
  2. Fatal Error LNK1220: 1 unresolved externals
    By zenghoong in forum C Programming
    Replies: 3
    Last Post: 10-12-2009, 03:24 AM
  3. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  4. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  5. debug to release modes
    By DavidP in forum Game Programming
    Replies: 5
    Last Post: 03-20-2003, 03:01 PM