This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

c++/10680: Inlining in inheritance seems broken.

>Number:         10680
>Category:       c++
>Synopsis:       Inlining in inheritance seems broken.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu May 08 13:16:00 UTC 2003
>Originator:     Michael Nielsen
>Release:        gcc version 3.2.1
Linux i686

Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/specs
Configured with: ../configure --enable-languages=c c++
Thread model: posix
gcc version 3.2.1
We have a class hierachy where there is a lot of inheritance, and functions (commonly used) are in the base of the tree, and the sub classes then use this functionality farther down..  But because the code is called a lot of times I'd really like the code to be inlined in the sub classes, so I put some inlines into the class definition, expecting the compiler to use this to inline the code as much as possible

I have reduced the code down to a few lines, and can reproduce the same issues with this trivial code example.

When creating a simple inheritance system, with two classes located in two different files (a.h, and b.h).

a.h : 

#include <list> 
class A {
		void a();

		void b();

		std::list<class A *> *_a;


#include "a.h"
#include <list>

class B : public A {

		std::list<A * > *_a;

The implementations of A and B are placed in a.cpp, and b.cpp, (see attachment for full code).

A program main.cpp creates an instance of B, to activate the classes, and cause a call to the inlined functions.

Then when compiling by.

g++ *.cpp -o testprog

The resulting message is:

/tmp/ccHXusSr.o: In function `B::B[not-in-charge]()':
/tmp/ccHXusSr.o(.text+0x18): undefined reference to `A::a()'
/tmp/ccHXusSr.o(.text+0x23): undefined reference to `A::b()'
/tmp/ccHXusSr.o: In function `B::B[in-charge]()':
/tmp/ccHXusSr.o(.text+0x42): undefined reference to `A::a()'
/tmp/ccHXusSr.o(.text+0x4d): undefined reference to `A::b()'
collect2: ld returned 1 exit status

It seems that the compiler has removed the inlined functions from the definition, and only inlined them in the a.o file, making them unavailable in the sub class B.   

This behaviour is different from what I expected.  

>From the C++ language definition the calls A::a(), and A::b() should be available in class B, however the compiler has removed the code, due to the inline, thus they are not available in B.

This seems to me, to be in conflict with the C++ language definition ?.   

I've tried adding the -fkeep-inline-functions, and this fixes the issue, however then enabling -O3 on the compiler, will then cause several of the std:: files such as 
bool std::lexicographical_compare to become multiply defined, when you use iostreams, and lists from stl.

Not sure if it is a bug, or an understanding issue.

take the included archive, and extract it, go to the directory testprog.

run make.
g++ *.cpp -o testprog -fkeep-inline-functions -O3
g++ *.cpp -o testprog -fkeep-inline-functions -finline-functions -O2

This will generate errors..

run the command 

g++ *.cpp -o testprog -fkeep-inline-functions
g++ *.cpp -o testprog -fkeep-inline-functions  -O2

And the code will compile flawlessly.

Temp work around, do not combine -O2 and -finline-functions, or use -O3.
Content-Type: application/x-bzip2; name="testprog.tar.bz2"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="testprog.tar.bz2"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]