3

Apparently, the new operator returns void*. So I was wondering what mechanism allows void* casting to A* when calling new A() to create a new instance of class A.

To illustrate:

// Example program
#include <iostream>
#include <string>

class A
{
public:
    A() {}    
};

void* createA()
{
    return new A();
}

int main()
{
    A* a1 = new A();
    A* a2 = createA();
    delete a1;
    delete a2;
}

A* a1 = new A() compiles fine (obviously).

A* a2 = createA() does not reporting error: error: invalid conversion from 'void*' to 'A*' (obviously too...).

Actually, the first one also does a conversion from void* to A. What mechanism or rule allows the first conversion and rejects the second one?

That's probably a stupid question....if so, sorry about that.

jpo38
  • 20,821
  • 10
  • 70
  • 151

2 Answers2

2

What you have here is a new expression, which in turn invokes operator new (followed by the appropriate conversion), plus the constructor.

From cppreference.com:

::(optional) new (placement_params)(optional) ( type ) initializer(optional)

Attempts to create an object of type, denoted by the type-id type ...

It won't work if you manually invoke operator new, e.g.

A* a2 = operator new(sizeof(A));

won't compile either.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • You mean it's an `expression` and the compiler silently transforms this into a call to the `operator` + a `cast`? – jpo38 Jan 02 '16 at 16:32
  • @jpo38 Yes, most likely. It is not just a plain call to `operator new`. – vsoftco Jan 02 '16 at 16:32
  • Got it. It makes sense and this question was probably a duplicate of http://stackoverflow.com/questions/16345340/does-new-return-void-in-c/16345393#16345393 references by James D – jpo38 Jan 02 '16 at 16:33
  • @jpo38 Oh yes, it is probably a dupe. – vsoftco Jan 02 '16 at 16:35
  • @jpo38 - there is no **cast**. There is a **conversion**. A cast is something you write in your source code to tell the compiler to do a conversion. That makes it an explicit conversion. The compiler can also do implicit conversions, i.e., conversions that are not signaled by a cast. – Pete Becker Jan 02 '16 at 16:56
  • @PeteBecker You're absolutely right, corrected my answer. – vsoftco Jan 02 '16 at 16:57
1

There is no cast here.

When the compiler sees a new expression, it first invokes the appropriate new operator (depending on the type and the arguments to the new keyword). That returns a pointer to a block of raw memory; such pointers are conventionally typed as void* since they do not refer to any object.

Then the appropriate constructors are executed (depending on the constructor arguments), starting with the base classes. The first step in executing a constructor is default-initializing the raw memory into which the object will be constructed. That includes initializing any internal metadata required by the object, such as its vtable if it includes a virtual method. Once that is finished, the memory region contains a nascent object, so this can be created with the correct type. Then the rest of the constructor can be executed (which might use this, either implicitly or explicitly).

Once all the constructors have been executed, the value of the new expression is the (typed) value of this.

rici
  • 234,347
  • 28
  • 237
  • 341