2

I have managed to find the GCC source code showing the new() operator making a call to malloc() in new_op.cc:

_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
  void *p;

  /* malloc (0) is unpredictable; avoid it.  */
  if (sz == 0)
    sz = 1;
  p = (void *) malloc (sz);
  while (p == 0)
    {
      new_handler handler = __new_handler;
      if (! handler)
    _GLIBCXX_THROW_OR_ABORT(bad_alloc());
      handler ();
      p = (void *) malloc (sz);
    }

  return p;
}

However, I am trying to find the code where the object constructor is invoked at the memory address returned from above (I presume placement new would be used??).

Where can I find this in GCC?

simonc
  • 41,632
  • 12
  • 85
  • 103
user3811839
  • 141
  • 7
  • You can change only the allocation - not the construction after 'new' returns –  Jul 30 '14 at 19:24
  • The constructor call is inserted at the site of the new-expression by the compiler. Simple example: http://goo.gl/T4uGmr. – T.C. Jul 30 '14 at 19:29
  • @T.C. Thanks! So where is the code which tells the constructor to put its allocation at the address returned from new operator? – user3811839 Jul 30 '14 at 19:38
  • @user3811839 Bit hard to explain the assembly in a comment. See my answer. – T.C. Jul 30 '14 at 19:54

2 Answers2

4

The constructor call is inserted at the site of the new-expression by the compiler. You can look at the disassembly of a simple program:

struct A { A() noexcept; ~A() = default; } ;
int main(){
    new A;
}

produces for the new A; expression (with g++ 4.9 at -O0 on Linux 64-bit):

movl    $1, %edi                         ; copy the size of A into edi (the lower 32 bits of `rdi`)
call    operator new(unsigned long)      ; call the operator new function to allocate memory
movq    %rax, %rdi                       ; copy the return value (in rax) to rdi
call    A::A()                           ; call the constructor

x64 calling convention on Linux for a function taking a single integer or pointer parameter is that the parameter is passed in the rdi register and the return value is placed in rax. (While A::A() seems to take no parameter, like all non-static class member functions, it has a hidden this parameter.) So in this case, the compiler generates code to copy the pointer returned by operator new() in rax to rdi, to be passed to A's constructor as the hidden this parameter, and then calls the constructor.

Note that this code is vastly simplified by declaring A::A() as noexcept, so the compiler can assume that the constructor call will never throw an exception.

As to placement new, it's implemented in the same way - except that it calls the placement operator new(size_t, void *) - whose implementation simply returns the pointer passed. The compiler then generates code that calls the constructor, passing the return value of the placement operator new() as the this parameter.

T.C.
  • 133,968
  • 17
  • 288
  • 421
2

operator new is just a plain old function, it only allocates bulk memory, it does not invoke constructors etc. It is the job of new keyword (sometimes called new operator, super confusing) to do the latter.

See Difference between 'new operator' and 'operator new'? for a similar question.

So when you call

Foo* foo = new Foo();

you actually first call operator new(sizeof(Foo)), that returns a pointer to the memory area that it allocates, then new is constructing the object in the memory returned by the first call by invoking the appropriate constructor/in-class initialization.

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Thanks. Ok so I guess my question is, can I see the code for "new keyword"? – user3811839 Jul 30 '14 at 19:36
  • Have no idea how/where it is internally implemented, but it is a feature of the language itself. It should probably be implemented somewhere though... Nowadays even the `C++` compiler is written in `C++`, so you should probably dig quite deep. – vsoftco Jul 30 '14 at 19:42