inheritance of inline functions

Posted on 2004-04-05
Last Modified: 2008-03-04
I am right now writing some code with a base class containing 3 inline functions to be inherited.  When I tried to compile the derived class it was having trouble finding the inline functions.  The program compiles fine when the functions are no longer inline.  I am compiling using the CC compiler on Solaris 9.  

Is there anything special that needs to be done to allow inline functions to be seen by the derived class?  Are there any compilier options that need to be set?  It is not vital for the functions to be inline but it frustrates me that I am unable to figure out why the compilier is giving me the problem.  


I apologize in advance for not being able to supply source code.
Question by:gkatz

Accepted Solution

guntherothk earned 70 total points
ID: 10758524
The body of your inline functions must be available in any context that *calls* the function.

It's kinda hard to tell what is going wrong with no source and no error messages, but here's some things to look for.

If a derived class overloads the same name with a function having a different signature, it hides the functions declared in the base class. You'd get a undeclared function message, and it wouldn't matter if the functions are inlined. You say the code compiles fine with the functions not inlined, so this probably isn't it.

If your inline functions are defined (have a body) inside the class declaration like

class Foo
    void f(int i) { return i+1; }

and you can't see the definition, you also won't see the declaration and you'll get a message like "function void Foo::f(int) not declared".

But since you can turn inlining on and off, I'd guess this isn't what you have. Betcha you have the bodies of your inlined functions declared in a separate file, like

// Foo.h
class Foo
    void f(int i);

// Foo.inl
# include "Foo.h"
inline void Foo::f(int i)
{return i+1;}

// main.cpp
#include "Foo.h"
int main(char**, int)
    return f(123);

In this case, the code would compile, but get an undefined symbol error for the symbol void Foo::f(int) from the linker. The problem in this example is that the inline definitions in Foo.inl aren't included in main.cpp.

When you use an .inl file, you have to include it somewhere. Typically you include it at the end of the .h file. Since you say you can turn inlining on and off, betcha you have something in your .h file like

# if defined USE_INLINE
#    define INLINE inline
#    include "Foo.inl"
# endif

and the definitions in your .inl file look like

INLINE void Foo::f(int i) { return i+1; }

You might look for spelling errors in whatever macro name takes the place of USE_INLINE in your code. If you've spelled it wrong, the function declarations are there but the bodies are missing, your code compiles but doesn't link.

Sometimes including inlines is delayed to the .cpp file because they reference other classes and you don't want to have to #include all those other headers in your .h file. Such a situation is just a recipe for nightmares. I've done it a few times, and nowadays I just include all the headers each header needs.

Conditional inlining can also interact with the "include me once" convention. Many projects surround their .h files with

# if !defined FOO_H
#    define FOO_H
class Foo ...

# endif // !defined FOO_H

If you want to control inlining on a file-by-file basis, and you use the use-me-once idiom, you can end up with your inline bodies not inclided in some circumstances. Since you didn't post your code, you'll have to just go through the file with the unresolved reference looking at each include file recursively to discover just what macros are set at what time. It's a tedious job. I recommend the "preprocess but don't compile" flag to CC, or a #pragma that prints out a message when processed as good debugging tools for this problem.

Author Comment

ID: 10759481
Thanks for the quick response.  
    You are correct I defined my inline functions in the cpp file instead of the h file.  I'm going to redefine my inline functions appropriately.

Thanks again

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

867 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

24 Experts available now in Live!

Get 1:1 Help Now