Re: [arm-gnu] Tons of seemly extraneous code linked in c++ program
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [arm-gnu] Tons of seemly extraneous code linked in c++ program



On Sun, May 29, 2011 at 01:06:54AM -0400, Gene Smith wrote:

> David Querbach wrote, On 05/28/2011 02:45 PM:
> >
> >Non-inlined destructors in g++ generate calls to operator delete() to handle
> >the case where the object was allocated using operator new().  delete() then
> >calls free(), which in turn brings in malloc(), which needs sbrk().
> >
> >If you really don't want malloc() and free() dragged in, write all of your
> >constructors inline and create all of your class objects in either static
> >memory or on the stack.  The compiler will then deduce that delete() is not
> >needed.
> >
> 
> Sorry, looking closer at this, I think I don't understand something
> here. I understand why you need to statically allocate or use
> locally declared objects to avoid malloc, but why do constructors
> need to be inline too? Or do you actually mean making the
> destructors inline is needed (since you only mention destructors in
> the 1st paragraph above). Or do you mean all ctors and dtors need to
> be inline?
> 
> Basically, I guess I don't understand the relation between inline
> ctor or dtor functions and whether an object can be created with new
> and removed with delete.

Sorry for the confusion.

Starting somewhere around version 3, g++ began generating multiple
constructors and destructors for different use cases, rather than generating
a single constructor and destructor with hidden arguments to select the
desired case.  I don't understand the issue completely, but the three cases
appear to be:

  - normal static or auto variables
  - dynamic variables (on the heap)
  - something involving multiple, perhaps virtual, inheritance.

If you write a trivial class and define its constructor and destructor
out-of-line, you should see multiple ctors and dtors in the generated code. 
Until your code is non-trivial, however, the optimizer will rip out all of
the "interesting" parts.

In some cases, destroying a heap-based class variable goes just as you would
expect:  call the dtor, then call ::operator delete().  In other cases, g++
puts the call to ::operator delete() _inside_ the dtor.  I can see this in
some of my production code, but can't identify under what circumstances g++
chooses to do so.

As for creating objects on the heap, it may be that my memory deceives me
and all such operations go as expected:  call ::operator new(), then call the
ctor.  In any case, I can't immediately find a counter-example in my
production code, so I may have been wrong.  It is true, however, that
defining ctors inline avoids the extra copy used for virtual inheritance.

I find that a clear majority of all my classes are instantiated in only one
place in the program, so avoiding the extra copies is a win.  On the other
hand, for simple ctors that are called often, making them inline allows the
optimizer to crunch them down, as well as avoiding the runtime overhead of a
function call.

Regards,

David Querbach
Real-Time Systems Inc.

Attachment: signature.asc
Description: Digital signature