Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come a new-expression can correctly produce the pointer type, even though it should return void*? [duplicate]

We know that void* holds no information regarding the actual type of the data it points to. However, from cppreference on new and new[] we know that those operators return void*. How come, then, given:

auto x = new int{};

knowing that the new operator should return void*, x is deduced to be of a type int*, not void*?

Consider yet another example:

struct foo {
    static void* operator new(std::size_t n) {
        std::cout << "new called!\n";
        return ::new char[n];
    }
};

let's add some TypeDisplayer:

template <typename T>
struct TD;

and the test code:

int main() {
    auto x = new foo{};

    TD<decltype(x)>{};
}

The code fails to compile with error indicating that decltype(x) is foo*. If we comment out the last line of main, we will know that our, void*-returning operator will be called due to new called! being printed.

like image 736
Fureeish Avatar asked Dec 28 '19 17:12

Fureeish


1 Answers

It's easy to confuse the new keyword with the operator new, but they're two different things. When you write a memory allocation function, its name is operator new and it does, as you say, return void*. But you don't ordinarily call that operator directly; instead, you create a new object with the new keyword. The compiler understands that keyword; it calls operator new to get memory for the object (or objects, for array new) that's being created and does whatever initialization is appropriate. The type of the result of that expression is a pointer to the type being created.

So, in the code

auto x = new int{};

the type of the expression new int{} is int*, so the deduced type for x is also int*.

like image 177
Pete Becker Avatar answered Nov 19 '22 02:11

Pete Becker