Solved

Undefined symbol for unused function

Posted on 2001-08-06
30
297 Views
Last Modified: 2008-02-01
Hi guys,
 I think I'm going crazy. I'm getting undefined symbols in the following situation

//Base.h

class Base{public:virtual void func(void)=0;}


//Intermediate.h
#include "Base.h"
class Intermediate:public Base
{};


//Derived.h
#include "Intermediate.h"
class Derived:public Intermediate{
public:virtual void func(void);}


The .C files *nowhere* have a statement which includes a call to func. Therefore I should not have to define it, only declare it.

And yet, when I try to link the object files (compilation is successful)
it gives me
"undefined symbol Derived::func(void) first referenced in file Derived.h"

Please tell me why this doesn't work.
0
Comment
Question by:glebspy
  • 10
  • 8
  • 6
  • +2
30 Comments
 
LVL 1

Author Comment

by:glebspy
ID: 6356223
Semicolons at the end of all the class definitions.
0
 
LVL 1

Expert Comment

by:RideOn
ID: 6356251
yup, that's right
0
 
LVL 1

Author Comment

by:glebspy
ID: 6356271
Of course that error wasn't present in the original, so the question still stands.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6356303
Btw main is of this form

//main.C
int main(void){
Derived derived;
return 0;
}
0
 
LVL 2

Expert Comment

by:Lockias
ID: 6356369
If you do not want to define the function for Derived, you need to make it pure virtual there as well.  The declaration of the function is in Base.  Then you say you are going to implement it in Derived.  Now, it is true that if you have nothing in your code that uses the function you should not have to define it. Almost true.  This would be true if it were not declared in Base.  However, it sees the actual declaration in Base, and then it assumes an implementation when you declare it as non pure virtual in the derived class.

~Lockias
0
 
LVL 1

Author Comment

by:glebspy
ID: 6356420
Ok, does it not work because func is virtual, or rather because it is *pure* virtual?
0
 
LVL 30

Expert Comment

by:Axter
ID: 6356444
>>or rather because it is *pure* virtual?
You can not use a class that has a pure virtual function directly.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6356451
If your base class has a pure virtual function, then your derive class must define it.
Just declaring it will not work, even if you don't make a reverence to it.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6356461
what would happen if it was an ordinary virtual function?
0
 
LVL 30

Expert Comment

by:Axter
ID: 6356469
Clarification:
///////////////////////////////////
If your base class has a pure virtual function, then your derive class must define it.
Just declaring it will not work, even if you don't make a reverence to it.
///////////////////////////////////
I'm of course referring to a derive class that has implementation.
0
 
LVL 2

Expert Comment

by:Lockias
ID: 6356492
Axter,
  That is what I said.

~Lockias
0
 
LVL 1

Author Comment

by:glebspy
ID: 6356511
what would happen if it was a non-pure virtual function?
0
 
LVL 1

Author Comment

by:glebspy
ID: 6356516
i.e. if it was virtual but wasn't pure?
0
 
LVL 2

Expert Comment

by:Lockias
ID: 6356536
If it was a non-pure virtual function in Base.h in think you should be fine.  I guess would take just a second to test though.

Why are you wanting to do this anyway?  Is this just a learning experiment?

~Lockias
0
 
LVL 1

Author Comment

by:glebspy
ID: 6356574
Far from it!
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
ID: 6356598
Here are the rules.

A member function may be declared in the class definition and not defined as long as it is not "used". (This is the official term.)  

Now a virtual function is always used.
A non-virtual function is potentially used depednding on the source code.

From the C++ standard 3.2.2

A  virtual member  function is used if it is not pure.

Then from 3.2.3

Every program shall contain exactly one definition of
every non-inline function  or  object  that  is  used  
in  that  program; no diagnostic required.

So you see that yoou can declre and not define a non-virtual function as long as you use it.  you can declare and not define a pure virtual function.  But if you declare a virtual function you must define it.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6356623
Thanks Nietod. Big thank you to Lockias and Axter too.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6357244
Correction and clarification:

>>So you see that yoou can declre and not define a non-
>>virtual function as long as you use it.  
That should be as long as you DONT use it.


>>you can declare and not define a pure virtual function.
An implemented decendant class must define it.


>>But if you declare a virtual function you must define
>>it.
This is true if the class has implementation.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6357251
Clarification on the clarification:
Correction and clarification:

>>So you see that yoou can declre and not define a non-
>>virtual function as long as you use it.  
That should be as long as you DONT use it.


>>you can declare and not define a pure virtual function.
A USED decendant class must define it.


>>But if you declare a virtual function you must define
>>it.
This is true if the class is USED.
0
 
LVL 22

Expert Comment

by:nietod
ID: 6357470
>> >>So you see that yoou can declre and not define a non-
>> >>virtual function as long as you use it.  
>> >> That should be as long as you DONT use it.
I jsut missed one word there,  Makes a big difference though.

>> >>you can declare and not define a pure virtual function.
>> An implemented decendant class must define it.
No.  You don't have to.

>> >>But if you declare a virtual function you must define
>> >>it.
>> This is true if the class has implementation.
What do you mean by "implimentation"?  Usually that means the definition of the functions.  So if you have implimentation, well then you have the definition.  That's just two expressions that mean the same thing.  On the other hand, if you don't have the implimentation you don't have to define it?  That's wrong.  A non-pure virtual function must be defined.  Period.  Not if anything.  That is all there is to it.  A non-pure virtual function must be defined.  A pure virtual function doesn't have to be defined.  A non-virtual function must be defined if it is used.  
0
 
LVL 30

Expert Comment

by:Axter
ID: 6358003
>>What do you mean by "implimentation"?  
That's why I re-posted the comment.  Check second posting.
0
 
LVL 22

Expert Comment

by:nietod
ID: 6358935
>> >>But if you declare a virtual function you must define
>> >>it.
>> This is true if the class is USED.
But that is wrong.  The class will be used if the class name appears in any potentially evaluated expression. So the class may or may not be used.  But in either case, the virtual function, if not pure, must be defined because the virtual function itself is used.  This has nothing to do with whethor or not the class is used.
0
 
LVL 2

Expert Comment

by:Lockias
ID: 6359914
Do you mean really used or sort of used?  Or really, really used but maybe not really.  I mean really, what sort of virtual functions are rarely really used?

~Lockias
0
 
LVL 22

Expert Comment

by:nietod
ID: 6359923
"used" means that something needs a definition (by link time), a declaration will not do.  Check that sectopn of the standard.
0
 
LVL 2

Expert Comment

by:Lockias
ID: 6360013
I guess if forgot to put the   :)
0
 
LVL 30

Expert Comment

by:Axter
ID: 6360256
>>This has nothing to do with whethor or not the
>>class is used.
I don't think you guys understand what I'm saying.

Example:

///////////////////////////////////////
class foo
{
public:
     foo(){};
     virtual void SomeFunction1(void);
};
int main(int argc, char* argv[])
{
     return 0;
}
///////////////////////////////////////
Even though the above code has a class with an undefined virtual function, the code will still compile because foo is not used in the implementation.
Since the class is not used, the compiler will ignore it.

///////////////////////////////////////
class foo
{
public:
     foo(){};
     virtual void SomeFunction1(void);
};
int main(int argc, char* argv[])
{
     foo some_foo;
     return 0;
}
///////////////////////////////////////
In the above code, foo is implemented via some_foo variable.
Even though nothing is done with some_foo, this is still considered implementation code, and the compiler will not allow you to compile foo without defining the virtual function.

In other words, if the class is not used in the implementation code, then there can be an undefine virtual function in the class.
0
 
LVL 22

Expert Comment

by:nietod
ID: 6360330
>> Even though the above code has a class with
>> an undefined virtual function, the code will
>> still compile because foo is not used in the
>> implementation.  Since the class is not used,
>> the compiler will ignore it.
Wrong.  While it will compile, it will not link.

3.2.2.
A  virtual
  member  function is used if it is not pure.

3.2.3
Every program shall contain exactly one definition of every non-inline
  function  or  object  that  is  used  in  that  program

nowhere does it say that the class has to be used.

>> In other words, if the class is not used in the >> implementation code, then there can be an
>> undefine virtual
Thanks for clarifying that incorrect point of view, which I've now had to correct 3 times.  Why don't you read the quotes I psoted from the standard.  I posted them twice.  That might be a good idea.
              function in the class.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6360405
>>Wrong.  While it will compile, it will not link.
Just to give you the benifit of the doubt, I tried it in both VC and GNU, and both will compile a class that has an undifine virtual function and not used in implementation code.

>>nowhere does it say that the class has to be used.
Are you blind???
It does say it right in the quote you posted.
What part of ["object  that  is  used  in  that  program"] do you not understand?

Before you complain about someone else reading your quotes, please first read it yourself.

If you don't understand something this simple, I don't see how you can be writing a C++ book.
0
 
LVL 22

Expert Comment

by:nietod
ID: 6360665
>> and both will compile a class
>> that has an undifine virtual function
>> and not used in implementation code.
And that proves what?

The standard specifically states that no diagnostic is required.   i.e. A program that contains this is ill-formed, but the compiler does nto have to treat t as such.  Does that change the fact that it is ill-formed?  no.

>> Before you complain about someone else
>> reading your quotes, please first read it
>> yourself.
Read it again.  You are not reading it correclty.
0
 
LVL 1

Author Comment

by:glebspy
ID: 6362433
Hi guys,
 I've lost a lot of time recently trying to find out why my code didn't *link*. I was using gcc2.95.

 I'm sure I had read somewhere that I could get away with not defining a (non-pure) virtual but I discovered to my cost that I couldn't, although as you pointed it seems to be allowed at compile-time .. I guess it could be expecting the definition to appear in another translation unit. I'm really grateful to you guys for clarifying this.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now