#operator new internals do not make any sense

46 messages · Page 1 of 1 (latest)

stiff yarrow
#
#include <iostream>

template<typename T>
void showType()
{
    1+1=6;
}

int main()
{
    char buf[50];
    using T1 = decltype(new (&buf) char('A'));
    using T2 = decltype(operator new(sizeof(char), &buf));
    showType<T1>();
    showType<T2>();
}

According to cppreference, placement new returns void*, that is supposed to be T2 but with testing the returned type is char* which is T1, this could have very big very scary UB from reinterpret_cast and its type aliasing rules. (replace char* with MyObject* for example)

Explain to me where I am wrong.

burnt swanBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

amber spoke
#

operator new returns void*

stiff yarrow
amber spoke
#

you're checking the result of the new expression, not of operator new

#

the new expression creates an object and returns a pointer to the created object

stiff yarrow
amber spoke
#

there's no cast

#
new (&buf) char('A')
```creates a `char` object in the given storage and returns a pointer to the object
#

don't confuse an operator new function with the new operator.

stiff yarrow
amber spoke
#

a new expression may call an operator new function to obtain storage for the object to be created. but the new expression and the operator new function are two completely different things.

#

the new expression does a lot more than just call operator new.

stiff yarrow
#

after memory has been obtained?

amber spoke
#

it creates an object, yes

stiff yarrow
#

ahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

#

so

#

so this new expression, where is its source code

#

or is that like, made with compiler support

amber spoke
#

it's like asking where's the source code for sizeof 😉

stiff yarrow
#

k, so...

#

this funky new expression, the T pointer returned by it, is it really safe to use? no UB ?

amber spoke
amber spoke
stiff yarrow
amber spoke
#

assuming that buff is large enough and correctly aligned, yes

stiff yarrow
#

Arr and buff both use natural alignment 1

#

but, if I tried to hack my way in with reinterpret_cast instead, it would be UB?

amber spoke
#

I don't think it's guaranteed that the alignment of Arr will be 1

#

it likely will be, but it doesn't have to be

stiff yarrow
amber spoke
stiff yarrow
amber spoke
stiff yarrow
amber spoke
#

it's completely up to the implementation

stiff yarrow
#

k, I guess I will have to static_assert alignments from now on lmao

amber spoke
#

just alignas the buffer accordingly

stiff yarrow
#

yes, same

amber spoke
#
char alignas(Arr) buff[sizeof(Arr)];
stiff yarrow
#

I will skip the details behind overriding operator new and all of its versions for now

#

!solved