当前草案标准明确说明,placement
在我看来,要析构这个数组,唯一的解决方案是在循环中调用析构函数(我对此理解正确吗?),因为没有 placement
我认为由于这种开销无法用于任何有用的事情,编译器不使用它(因此这在实践中不是一个问题)。我已经检查过这个简单代码的编译器:
GCC和clang根本不使用任何开销。但是,MSVC在
这是一些背景信息,解释了我提出这个问题的原因。
以前有关于这个主题的问题:
- Array placement-new requires unspecified overhead in the buffer? - Can placement new for arrays be used in a portable way? 就我所看到的,这些问题的道德准则是避免使用放置
new[]
可能会有空间开销:
所以他们可能已经考虑到了编译器为什么需要这种开销。这是为什么?编译器能否利用这种开销做出任何有用的事情?这个开销可能适用于所有数组 new-expressions,包括那些引用库函数 operator new[](std::size_t, void*) 和其他放置分配函数的表达式。开销量可能因每次新调用而异。
在我看来,要析构这个数组,唯一的解决方案是在循环中调用析构函数(我对此理解正确吗?),因为没有 placement
delete[]
(顺便说一句,我们不应该有 placement delete[]
来正确地析构数组,而不仅仅是它的元素吗?)。所以编译器不必知道数组长度。我认为由于这种开销无法用于任何有用的事情,编译器不使用它(因此这在实践中不是一个问题)。我已经检查过这个简单代码的编译器:
#include <stdio.h>
#include <new>
struct Foo {
~Foo() { }
};
int main() {
char buffer1[1024];
char buffer2[1024];
float *fl = new(buffer1) float[3];
Foo *foo = new(buffer2) Foo[3];
printf("overhead for float[]: %d\n", (int)(reinterpret_cast<char*>(fl) - buffer1));
printf("overhead for Foo[] : %d\n", (int)(reinterpret_cast<char*>(foo) - buffer2));
}
GCC和clang根本不使用任何开销。但是,MSVC在
Foo
情况下使用8个字节的开销。MSVC可能出于什么目的使用这种开销?
这是一些背景信息,解释了我提出这个问题的原因。
以前有关于这个主题的问题:
- Array placement-new requires unspecified overhead in the buffer? - Can placement new for arrays be used in a portable way? 就我所看到的,这些问题的道德准则是避免使用放置
new[]
,而是在循环中使用放置new
。但是这种解决方案不会创建数组,而是创建相邻的元素,这不是一个数组,对它们使用operator[]
是未定义的行为。这些问题更多的是关于如何避免放置new[]
,但这个问题更多的是关于“为什么”。
placement new[]
的调用是完全多余的,并将其删除了! https://godbolt.org/g/94Deyp - Richard Hodgesnew(buffer2) Foo[3];
移到一个单独的函数中(并将buffer2
作为输入参数),则也相同。所以这不是优化问题。 - geza