public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* GCC C++ & inlining problem
@ 2002-12-16  8:26 Brenner Joel
  2002-12-16 13:19 ` Andreas Conz
  0 siblings, 1 reply; 2+ messages in thread
From: Brenner Joel @ 2002-12-16  8:26 UTC (permalink / raw)
  To: gcc

There seems to be a number of problems with GCC inlining class member
functions in C++ code,
it is not clear if these are different manifestations of a single problem or
are separate problems,
however they appear to be serious errors resulting in significant code
growth and sometimes making
it impossible to link the resulting object files.



Assume we have a class ClassA declared in a file and we instantiate the
class and give it a value in the same file

test.cpp

		class ClassA{
			int Value;
		public:
			ClassA(){}
			~ClassA(){}
			ClassA & operator=(const int op1){
				Value =  op1;
				return *this;
			}
			ClassA & operator*=(const int op2){
				Value *= op2;
				return *this;
			}
		};


		void test(void){
			ClassA x;
			x = 1;
		}


this compiles OK and produces a small executable about 2K bytes.

Now if we move the class to ClassA.h and include it we get the same results.

Next, split the class declaration into ClassA.h and it's definition also in
ClassA.cpp as so

ClassA.h
		class ClassA{
			int Value;
		public:
			ClassA();
			~ClassA();
			ClassA & operator=(const int op1);
			ClassA & operator*=(const int op2);

		};

		ClassA::ClassA(){}
		ClassA::~ClassA(){}
		ClassA & ClassA::operator=(const int op1){
			Value =  op1;
			return *this;
		}
		ClassA & ClassA::operator*=(const int op2){
			Value *= op2;
			return *this;
		}

test.cpp
		#include "ClassA.h"
		void test(void){
			ClassA x;
			x = 1;
		}

This still compiles Ok and produces a 2K object file.


now we move the class definition into ClassA.cpp
ClassA.h
		class ClassA{
			int Value;
		public:
			ClassA();
			~ClassA();
			ClassA & operator=(const int op1);
			ClassA & operator*=(const int op2);

		};

ClassA.cpp
		#include "ClassA.h"
		ClassA::ClassA(){}
		ClassA::~ClassA(){}
		ClassA & ClassA::operator=(const int op1){
			Value =  op1;
			return *this;
		}
		ClassA & ClassA::operator*=(const int op2){
			Value *= op2;
			return *this;
		}

test.cpp
		#include "ClassA.h"
		void test(void){
			ClassA x;
			x = 1;
		}


re-compile and the code size increases to about 25 K bytes.

next, try making the functions inline by adding the inline keyword
ClassA.cpp
		#include "ClassA.h"
		inline ClassA::ClassA(){}
		inline ClassA::~ClassA(){}
		inline ClassA & ClassA::operator=(const int op1){
			Value =  op1;
			return *this;
		}
		inline ClassA & ClassA::operator*=(const int op2){
			Value *= op2;
			return *this;
		}


the program will no longer link, all of the operators and constructors of
class A are now unresolved.


Taking this further, if we define a class ClassB which instantiates member
variables of type ClassA,

if we define and declare ClassA entirely in ClassA.h, and ClassB entirely in
ClassB.h then everything is fine and
we get a small executable.

If we then revert to the 2 file version for ClassA (with or without without
the inline specifier), the program will
no longer link since all references by ClassB to ClassA are unresolved

If we also change ClassB to a 2 file version and do not specify 'inline' for
either then the program will link
but has again grown to over 25K.













-- 
Joel Brenner   -- Designer    
E-mail: joel.brenner@nemerix.com
Phone:  +41 91 612 46 00 -- Fax : +41 91 612 47 01
Direct: +41 91 612 47 12
www.nemerix.com

NemeriX SA Stabile Gerre 2000
PO Box 425 6928 Manno, Switzerland
----------



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: GCC C++ & inlining problem
  2002-12-16  8:26 GCC C++ & inlining problem Brenner Joel
@ 2002-12-16 13:19 ` Andreas Conz
  0 siblings, 0 replies; 2+ messages in thread
From: Andreas Conz @ 2002-12-16 13:19 UTC (permalink / raw)
  To: Brenner Joel; +Cc: gcc

On Mon, 16 Dec 2002, Brenner Joel wrote:

> There seems to be a number of problems with GCC inlining class member
> functions in C++ code, it is not clear if these are different
> manifestations of a single problem or are separate problems, however

Yes they are the manifastation of the same problem. You should take a look
in i.e. Stroustrup "The C++ Programming Language". In my german version,
4th edition your problem is described in Chapter 9 "Quelldateien und
Programme". Should be something about organizing source code files.

> they appear to be serious errors resulting in significant code growth
> and sometimes making it impossible to link the resulting object files.
>
> test.cpp
>
> 		class ClassA{
> 			int Value;
> 		public:
> 			ClassA(){}
> 			~ClassA(){}
> 			ClassA & operator=(const int op1){
> 				Value =  op1;
> 				return *this;
> 			}
> 			ClassA & operator*=(const int op2){
> 				Value *= op2;
> 				return *this;
> 			}
> 		};
>
>
> 		void test(void){
> 			ClassA x;
> 			x = 1;
> 		}
>
>
> this compiles OK and produces a small executable about 2K bytes.

OK, no problem here.

> Now if we move the class to ClassA.h and include it we get the same results.
>
> Next, split the class declaration into ClassA.h and it's definition also in
> ClassA.cpp as so
>
> ClassA.h
> 		class ClassA{
> 			int Value;
> 		public:
> 			ClassA();
> 			~ClassA();
> 			ClassA & operator=(const int op1);
> 			ClassA & operator*=(const int op2);
>
> 		};
>
> 		ClassA::ClassA(){}
> 		ClassA::~ClassA(){}
> 		ClassA & ClassA::operator=(const int op1){
> 			Value =  op1;
> 			return *this;
> 		}
> 		ClassA & ClassA::operator*=(const int op2){
> 			Value *= op2;
> 			return *this;
> 		}
>
> test.cpp
> 		#include "ClassA.h"
> 		void test(void){
> 			ClassA x;
> 			x = 1;
> 		}
>
> This still compiles Ok and produces a 2K object file.
Yes, everything is visible to the compile while translating test.cpp.

> now we move the class definition into ClassA.cpp
> ClassA.h
> 		class ClassA{
> 			int Value;
> 		public:
> 			ClassA();
> 			~ClassA();
> 			ClassA & operator=(const int op1);
> 			ClassA & operator*=(const int op2);
>
> 		};
>
> ClassA.cpp
> 		#include "ClassA.h"
> 		ClassA::ClassA(){}
> 		ClassA::~ClassA(){}
> 		ClassA & ClassA::operator=(const int op1){
> 			Value =  op1;
> 			return *this;
> 		}
> 		ClassA & ClassA::operator*=(const int op2){
> 			Value *= op2;
> 			return *this;
> 		}
>
> test.cpp
> 		#include "ClassA.h"
> 		void test(void){
> 			ClassA x;
> 			x = 1;
> 		}
>
> re-compile and the code size increases to about 25 K bytes.
>
That is OK too. The compiler does not know the meaning of the operators
while compiling test.cpp, becaus only ClassA.h is visible. So function
calls and some other things are introduced. This grows the binary.

> next, try making the functions inline by adding the inline keyword
> ClassA.cpp
> 		#include "ClassA.h"
> 		inline ClassA::ClassA(){}
> 		inline ClassA::~ClassA(){}
> 		inline ClassA & ClassA::operator=(const int op1){
> 			Value =  op1;
> 			return *this;
> 		}
> 		inline ClassA & ClassA::operator*=(const int op2){
> 			Value *= op2;
> 			return *this;
> 		}
>
>
> the program will no longer link, all of the operators and constructors of
> class A are now unresolved.

This behaviour is correct. There are no functions to be called from
test.cpp, because they are inlined in ClassA.cpp. So the linker is
unhappy.

mit freundliche Gruessen / kind regards
Andreas Conz

WWW    http://www.neuro.informatik.uni-kassel.de/~andreasc
e-mail andreasc@neuro.informatik.uni-kassel.de



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-12-16 21:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-16  8:26 GCC C++ & inlining problem Brenner Joel
2002-12-16 13:19 ` Andreas Conz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).