Cryptic compiler error, maybe to do with use of “virtual”?











up vote
0
down vote

favorite












I'm getting this compiler error. I have several hundred lines of code, so I'll post some that I think might be relevant but you'll need to tell me what you want to see.



Here's the error I get at compile time:



/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1067): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x17a5): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1ee6): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x2560): undefined reference to `vtable for Person'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: /tmp/ccBE5kZ5.o: bad reloc address 0xc in section `.text$_ZN6WeaponD1Ev[Weapon::~Weapon()]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: final link failed: Invalid operation
collect2: ld returned 1 exit status


Here's the declaration of my Person class and my Weapon class, and the Actor class the Person is a descendant of:



class Actor {
public:
virtual void act();
virtual string getName();
virtual void setName(string n);
Actor();
Actor(string n);
virtual ~Actor();
private:
string name;
};


class Person : public Actor {
public:
void act();
virtual void fight(Person enemy);
virtual void takeDamage(double dmg);

// getters and setters
virtual unsigned getX();
virtual void setX(unsigned amt);
virtual unsigned getY();
virtual void setY(unsigned amt);
virtual Weapon getWeapon();
virtual void setWeapon(Weapon w);
virtual Weapon getArmor();
virtual void setArmor(Weapon a);
virtual unsigned getLevel();
virtual void setLevel(unsigned amt);
virtual double getHealth();
virtual void setHealth(double amt);
virtual double getXP();
virtual void setXP(double amt);
Person();
Person(string n);
private:
Weapon wep;
Weapon armor;
double xp;
unsigned level;
double health;
unsigned x;
unsigned y;
};


class Weapon {
public:
double getStrength();
void setStrength(double s);
double getValue();
void setValue(double amt);
double getHealth();
void setHealth(double amt);
string getName();
void setName(string n);
string getType();
void setType(string t);
Weapon();
Weapon(string n, string t, double dmg);
private:
string name;
string type;
double value;
double health;
double strength;
};









share|improve this question
























  • Added [gcc] tag as it seemed relevant and accurate.
    – John Dibling
    May 19 '12 at 2:28






  • 2




    vtable errors occur when you invoke an object of a class which doesn't have the definitions of the virtual methods (even though you may not be calling any methods). Where are the definitions, are they present in .cpp files ?
    – iammilind
    May 19 '12 at 2:28

















up vote
0
down vote

favorite












I'm getting this compiler error. I have several hundred lines of code, so I'll post some that I think might be relevant but you'll need to tell me what you want to see.



Here's the error I get at compile time:



/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1067): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x17a5): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1ee6): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x2560): undefined reference to `vtable for Person'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: /tmp/ccBE5kZ5.o: bad reloc address 0xc in section `.text$_ZN6WeaponD1Ev[Weapon::~Weapon()]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: final link failed: Invalid operation
collect2: ld returned 1 exit status


Here's the declaration of my Person class and my Weapon class, and the Actor class the Person is a descendant of:



class Actor {
public:
virtual void act();
virtual string getName();
virtual void setName(string n);
Actor();
Actor(string n);
virtual ~Actor();
private:
string name;
};


class Person : public Actor {
public:
void act();
virtual void fight(Person enemy);
virtual void takeDamage(double dmg);

// getters and setters
virtual unsigned getX();
virtual void setX(unsigned amt);
virtual unsigned getY();
virtual void setY(unsigned amt);
virtual Weapon getWeapon();
virtual void setWeapon(Weapon w);
virtual Weapon getArmor();
virtual void setArmor(Weapon a);
virtual unsigned getLevel();
virtual void setLevel(unsigned amt);
virtual double getHealth();
virtual void setHealth(double amt);
virtual double getXP();
virtual void setXP(double amt);
Person();
Person(string n);
private:
Weapon wep;
Weapon armor;
double xp;
unsigned level;
double health;
unsigned x;
unsigned y;
};


class Weapon {
public:
double getStrength();
void setStrength(double s);
double getValue();
void setValue(double amt);
double getHealth();
void setHealth(double amt);
string getName();
void setName(string n);
string getType();
void setType(string t);
Weapon();
Weapon(string n, string t, double dmg);
private:
string name;
string type;
double value;
double health;
double strength;
};









share|improve this question
























  • Added [gcc] tag as it seemed relevant and accurate.
    – John Dibling
    May 19 '12 at 2:28






  • 2




    vtable errors occur when you invoke an object of a class which doesn't have the definitions of the virtual methods (even though you may not be calling any methods). Where are the definitions, are they present in .cpp files ?
    – iammilind
    May 19 '12 at 2:28















up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm getting this compiler error. I have several hundred lines of code, so I'll post some that I think might be relevant but you'll need to tell me what you want to see.



Here's the error I get at compile time:



/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1067): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x17a5): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1ee6): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x2560): undefined reference to `vtable for Person'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: /tmp/ccBE5kZ5.o: bad reloc address 0xc in section `.text$_ZN6WeaponD1Ev[Weapon::~Weapon()]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: final link failed: Invalid operation
collect2: ld returned 1 exit status


Here's the declaration of my Person class and my Weapon class, and the Actor class the Person is a descendant of:



class Actor {
public:
virtual void act();
virtual string getName();
virtual void setName(string n);
Actor();
Actor(string n);
virtual ~Actor();
private:
string name;
};


class Person : public Actor {
public:
void act();
virtual void fight(Person enemy);
virtual void takeDamage(double dmg);

// getters and setters
virtual unsigned getX();
virtual void setX(unsigned amt);
virtual unsigned getY();
virtual void setY(unsigned amt);
virtual Weapon getWeapon();
virtual void setWeapon(Weapon w);
virtual Weapon getArmor();
virtual void setArmor(Weapon a);
virtual unsigned getLevel();
virtual void setLevel(unsigned amt);
virtual double getHealth();
virtual void setHealth(double amt);
virtual double getXP();
virtual void setXP(double amt);
Person();
Person(string n);
private:
Weapon wep;
Weapon armor;
double xp;
unsigned level;
double health;
unsigned x;
unsigned y;
};


class Weapon {
public:
double getStrength();
void setStrength(double s);
double getValue();
void setValue(double amt);
double getHealth();
void setHealth(double amt);
string getName();
void setName(string n);
string getType();
void setType(string t);
Weapon();
Weapon(string n, string t, double dmg);
private:
string name;
string type;
double value;
double health;
double strength;
};









share|improve this question















I'm getting this compiler error. I have several hundred lines of code, so I'll post some that I think might be relevant but you'll need to tell me what you want to see.



Here's the error I get at compile time:



/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1067): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x17a5): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x1ee6): undefined reference to `vtable for Person'
/tmp/ccBE5kZ5.o:game.cpp:(.text+0x2560): undefined reference to `vtable for Person'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: /tmp/ccBE5kZ5.o: bad reloc address 0xc in section `.text$_ZN6WeaponD1Ev[Weapon::~Weapon()]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: final link failed: Invalid operation
collect2: ld returned 1 exit status


Here's the declaration of my Person class and my Weapon class, and the Actor class the Person is a descendant of:



class Actor {
public:
virtual void act();
virtual string getName();
virtual void setName(string n);
Actor();
Actor(string n);
virtual ~Actor();
private:
string name;
};


class Person : public Actor {
public:
void act();
virtual void fight(Person enemy);
virtual void takeDamage(double dmg);

// getters and setters
virtual unsigned getX();
virtual void setX(unsigned amt);
virtual unsigned getY();
virtual void setY(unsigned amt);
virtual Weapon getWeapon();
virtual void setWeapon(Weapon w);
virtual Weapon getArmor();
virtual void setArmor(Weapon a);
virtual unsigned getLevel();
virtual void setLevel(unsigned amt);
virtual double getHealth();
virtual void setHealth(double amt);
virtual double getXP();
virtual void setXP(double amt);
Person();
Person(string n);
private:
Weapon wep;
Weapon armor;
double xp;
unsigned level;
double health;
unsigned x;
unsigned y;
};


class Weapon {
public:
double getStrength();
void setStrength(double s);
double getValue();
void setValue(double amt);
double getHealth();
void setHealth(double amt);
string getName();
void setName(string n);
string getType();
void setType(string t);
Weapon();
Weapon(string n, string t, double dmg);
private:
string name;
string type;
double value;
double health;
double strength;
};






c++ gcc virtual undefined






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 17 at 10:51









yugr

6,73221339




6,73221339










asked May 19 '12 at 2:25









ChemicalRocketeer

329316




329316












  • Added [gcc] tag as it seemed relevant and accurate.
    – John Dibling
    May 19 '12 at 2:28






  • 2




    vtable errors occur when you invoke an object of a class which doesn't have the definitions of the virtual methods (even though you may not be calling any methods). Where are the definitions, are they present in .cpp files ?
    – iammilind
    May 19 '12 at 2:28




















  • Added [gcc] tag as it seemed relevant and accurate.
    – John Dibling
    May 19 '12 at 2:28






  • 2




    vtable errors occur when you invoke an object of a class which doesn't have the definitions of the virtual methods (even though you may not be calling any methods). Where are the definitions, are they present in .cpp files ?
    – iammilind
    May 19 '12 at 2:28


















Added [gcc] tag as it seemed relevant and accurate.
– John Dibling
May 19 '12 at 2:28




Added [gcc] tag as it seemed relevant and accurate.
– John Dibling
May 19 '12 at 2:28




2




2




vtable errors occur when you invoke an object of a class which doesn't have the definitions of the virtual methods (even though you may not be calling any methods). Where are the definitions, are they present in .cpp files ?
– iammilind
May 19 '12 at 2:28






vtable errors occur when you invoke an object of a class which doesn't have the definitions of the virtual methods (even though you may not be calling any methods). Where are the definitions, are they present in .cpp files ?
– iammilind
May 19 '12 at 2:28














2 Answers
2






active

oldest

votes

















up vote
8
down vote













Your error boils down to the One Definition Rule (ODR) and the requirements that the language places on programs. In particular the requirement that every function that is used must be defined. A non-virtual function is considered odr-used if it is called, or it's address is taken. All virtual functions are odr-used and thus must be defined in your program.



Going back to the exact error in your program, it is probably due to how the GCC compiler deals with the generation of the virtual tables, which basically boils down to a simple rule: the virtual table is defined in the translation unit that holds the definition of the first non-inline virtual function in the class. If all virtual functions are inline, then the vtable will be generated in each and all translation units that include the definition of the class.



It seems that in your case, there is at least one virtual function that is not declared inline or defined in one of the translation units that get linked in the program. If the first non-inline virtual function was defined in one of the translation units, then the vtable would have been generated, and you would get a different error message regarding the lack of definition of any of the virtual functions for which there is no definition.






share|improve this answer





















  • Thanks for the thorough explanation
    – ChemicalRocketeer
    May 19 '12 at 3:52


















up vote
1
down vote













It's saying that there are virtual fields in Person which are not defined. So far we can see your declarations, but not definitions. Check that every virtual field in Person, including those inherited, is defined.






share|improve this answer





















  • Oh, I never gave it an act() method! Derp. Thanks for the help!
    – ChemicalRocketeer
    May 19 '12 at 3:52











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f10661833%2fcryptic-compiler-error-maybe-to-do-with-use-of-virtual%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
8
down vote













Your error boils down to the One Definition Rule (ODR) and the requirements that the language places on programs. In particular the requirement that every function that is used must be defined. A non-virtual function is considered odr-used if it is called, or it's address is taken. All virtual functions are odr-used and thus must be defined in your program.



Going back to the exact error in your program, it is probably due to how the GCC compiler deals with the generation of the virtual tables, which basically boils down to a simple rule: the virtual table is defined in the translation unit that holds the definition of the first non-inline virtual function in the class. If all virtual functions are inline, then the vtable will be generated in each and all translation units that include the definition of the class.



It seems that in your case, there is at least one virtual function that is not declared inline or defined in one of the translation units that get linked in the program. If the first non-inline virtual function was defined in one of the translation units, then the vtable would have been generated, and you would get a different error message regarding the lack of definition of any of the virtual functions for which there is no definition.






share|improve this answer





















  • Thanks for the thorough explanation
    – ChemicalRocketeer
    May 19 '12 at 3:52















up vote
8
down vote













Your error boils down to the One Definition Rule (ODR) and the requirements that the language places on programs. In particular the requirement that every function that is used must be defined. A non-virtual function is considered odr-used if it is called, or it's address is taken. All virtual functions are odr-used and thus must be defined in your program.



Going back to the exact error in your program, it is probably due to how the GCC compiler deals with the generation of the virtual tables, which basically boils down to a simple rule: the virtual table is defined in the translation unit that holds the definition of the first non-inline virtual function in the class. If all virtual functions are inline, then the vtable will be generated in each and all translation units that include the definition of the class.



It seems that in your case, there is at least one virtual function that is not declared inline or defined in one of the translation units that get linked in the program. If the first non-inline virtual function was defined in one of the translation units, then the vtable would have been generated, and you would get a different error message regarding the lack of definition of any of the virtual functions for which there is no definition.






share|improve this answer





















  • Thanks for the thorough explanation
    – ChemicalRocketeer
    May 19 '12 at 3:52













up vote
8
down vote










up vote
8
down vote









Your error boils down to the One Definition Rule (ODR) and the requirements that the language places on programs. In particular the requirement that every function that is used must be defined. A non-virtual function is considered odr-used if it is called, or it's address is taken. All virtual functions are odr-used and thus must be defined in your program.



Going back to the exact error in your program, it is probably due to how the GCC compiler deals with the generation of the virtual tables, which basically boils down to a simple rule: the virtual table is defined in the translation unit that holds the definition of the first non-inline virtual function in the class. If all virtual functions are inline, then the vtable will be generated in each and all translation units that include the definition of the class.



It seems that in your case, there is at least one virtual function that is not declared inline or defined in one of the translation units that get linked in the program. If the first non-inline virtual function was defined in one of the translation units, then the vtable would have been generated, and you would get a different error message regarding the lack of definition of any of the virtual functions for which there is no definition.






share|improve this answer












Your error boils down to the One Definition Rule (ODR) and the requirements that the language places on programs. In particular the requirement that every function that is used must be defined. A non-virtual function is considered odr-used if it is called, or it's address is taken. All virtual functions are odr-used and thus must be defined in your program.



Going back to the exact error in your program, it is probably due to how the GCC compiler deals with the generation of the virtual tables, which basically boils down to a simple rule: the virtual table is defined in the translation unit that holds the definition of the first non-inline virtual function in the class. If all virtual functions are inline, then the vtable will be generated in each and all translation units that include the definition of the class.



It seems that in your case, there is at least one virtual function that is not declared inline or defined in one of the translation units that get linked in the program. If the first non-inline virtual function was defined in one of the translation units, then the vtable would have been generated, and you would get a different error message regarding the lack of definition of any of the virtual functions for which there is no definition.







share|improve this answer












share|improve this answer



share|improve this answer










answered May 19 '12 at 2:33









David Rodríguez - dribeas

172k16231430




172k16231430












  • Thanks for the thorough explanation
    – ChemicalRocketeer
    May 19 '12 at 3:52


















  • Thanks for the thorough explanation
    – ChemicalRocketeer
    May 19 '12 at 3:52
















Thanks for the thorough explanation
– ChemicalRocketeer
May 19 '12 at 3:52




Thanks for the thorough explanation
– ChemicalRocketeer
May 19 '12 at 3:52












up vote
1
down vote













It's saying that there are virtual fields in Person which are not defined. So far we can see your declarations, but not definitions. Check that every virtual field in Person, including those inherited, is defined.






share|improve this answer





















  • Oh, I never gave it an act() method! Derp. Thanks for the help!
    – ChemicalRocketeer
    May 19 '12 at 3:52















up vote
1
down vote













It's saying that there are virtual fields in Person which are not defined. So far we can see your declarations, but not definitions. Check that every virtual field in Person, including those inherited, is defined.






share|improve this answer





















  • Oh, I never gave it an act() method! Derp. Thanks for the help!
    – ChemicalRocketeer
    May 19 '12 at 3:52













up vote
1
down vote










up vote
1
down vote









It's saying that there are virtual fields in Person which are not defined. So far we can see your declarations, but not definitions. Check that every virtual field in Person, including those inherited, is defined.






share|improve this answer












It's saying that there are virtual fields in Person which are not defined. So far we can see your declarations, but not definitions. Check that every virtual field in Person, including those inherited, is defined.







share|improve this answer












share|improve this answer



share|improve this answer










answered May 19 '12 at 2:32









Ashe

13.7k44166




13.7k44166












  • Oh, I never gave it an act() method! Derp. Thanks for the help!
    – ChemicalRocketeer
    May 19 '12 at 3:52


















  • Oh, I never gave it an act() method! Derp. Thanks for the help!
    – ChemicalRocketeer
    May 19 '12 at 3:52
















Oh, I never gave it an act() method! Derp. Thanks for the help!
– ChemicalRocketeer
May 19 '12 at 3:52




Oh, I never gave it an act() method! Derp. Thanks for the help!
– ChemicalRocketeer
May 19 '12 at 3:52


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f10661833%2fcryptic-compiler-error-maybe-to-do-with-use-of-virtual%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

"Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

Alcedinidae

RAC Tourist Trophy