在历史代码中不寻常地使用新的.这是什么意思?

Mar*_*ork 5 c++ legacy-code placement-new new-operator

我只是移植了一些旧代码:

#define NewArrayOnHeap(TYPE, COUNT, HEAP, NEWPTR, ERROR) \
((*(NEWPTR) = new ( #TYPE "[" #COUNT "]", __alignof(TYPE), (HEAP), &hr, (ERROR)) TYPE[COUNT] ), hr)
Run Code Online (Sandbox Code Playgroud)

看起来原版应该定义他们自己的魔法new操作符.我很好奇这种用法.

用法示例

int main()
{
    void*   heap = /* Don't know how to define this */
    double* ptr;
    HRESULT hr;

    hr = NewArrayOnHeap(double, 10, heap, ptr, "Help /* Just guessing here */");
}
Run Code Online (Sandbox Code Playgroud)

当我g++ -E用来获取预处理器输出时,它是:

int main()
{
    double* ptr;
    HRESULT hr;

    hr = ((*(ptr) = new ( "double[ 10 ]", __alignof(double), (NULL), &hr, ("Help")) double[10] ), hr);
}
Run Code Online (Sandbox Code Playgroud)

这看起来更像是一个placement new.

但这现在是一个重载的新调用(带有一些时髦的参数,一个五个参数new调用),或者这里是逗号运算符的逗号,因此它被缩减为("Help")(这没有意义).

new历史上(甚至现在)允许有两个以上的参数,(size, hint)

任何解码帮助将不胜感激.

GMa*_*ckG 7

您要查看的部分是§5.3.4/ 11-12,在此处解释:

new-placement语法用于为分配函数提供其他参数.如果使用,则对通过组合参数列表创建的函数调用执行重载解析,该参数列表包括请求的空间量(第一个参数)和new-expression的新放置部分中的表达式(第二个和后续参数) .第一个参数的类型为size_t,其余参数在new-placement中具有相应的表达式类型.

[示例:
- new T导致调用operator new(sizeof(T)),
- new(2,f)T导致调用operator new(sizeof(T),2,f),
- new T [ 5]导致调用operator new,并且
- new(2,f)T [5]导致调用operator new [](sizeof(T)*5 + y,2,f).

所以你的宏,要正确使用,需要在某处operator new定义类似于:

void* operator new[](size_t, const char*, size_t, void*, HRESULT*, const char*);
Run Code Online (Sandbox Code Playgroud)

我怀疑使用给它的信息来分配满足对齐要求的内存(可能来自预先分配的源),同时记录此分配并在无法进行分配时提供自定义错误消息.

就个人而言,我发现它很严重.:)


您所引用的典型"placement new"运算符是在其中定义的<new>,并且只是另一个接受a void*并将其作为分配结果返回的重载.