此问题在此处已有答案:
Optimization of raw new[]/delete[] vs std::vector(1个答案)
两年前关闭了。
在尝试之后,我想知道为什么GCC能够在未使用的malloc
或new
缓冲区上执行DCE,而不能在未使用的vector
上执行DCE?malloc
用例:https://godbolt.org/z/xKx5Y1
void fun() {
int *x = (int *)malloc(sizeof(int) * 100);
}
产生的组件:
fun():
ret
new
shell :https://godbolt.org/z/66drKr
void fun() {
int *x = new int[100];
}
产生的组件:
fun():
ret
vector
shell :https://godbolt.org/z/TWhE1E
void fun() {
vector<int> x(100);
}
产生的组件:
fun():
sub rsp, 8
mov edi, 400
call operator new(unsigned long)
mov esi, 400
lea rdi, [rax+8]
mov rcx, rax
mov QWORD PTR [rax], 0
mov r8, rax
mov QWORD PTR [rax+392], 0
and rdi, -8
xor eax, eax
sub rcx, rdi
add ecx, 400
shr ecx, 3
rep stosq
mov rdi, r8
add rsp, 8
jmp operator delete(void*, unsigned long)
2条答案
按热度按时间wribegjk1#
自C++14起,从新#分配:
允许新表达式省略或合并通过可替换分配函数进行的分配。在省略的情况下,编译器可以提供存储空间,而不调用分配函数(这也允许优化掉未使用的新表达式)。
注意,这种优化仅在使用new-expression时才被允许,而不是使用任何其他方法来调用可替换的分配函数:
delete[] new int[10];
可以被优化掉,但是operator delete(operator new(10));
不能。而
std::vector
使用的默认allocator使用后者,因此您建议的优化被禁止(因为 * as-if * 规则可能仍然适用,但那些操作符可能已经被替换,因此很难证明没有副作用)。如果提供自定义分配器,可能会得到预期的优化:Demo .
s3fp2yjn2#
好吧,仅仅因为
vector
是一个 * 类 *。换句话说,一个可能很复杂的软件对象。当你示例化它的一个示例时,它的“构造函数”必须被调用。很多事情发生了,应用程序员 * 故意 * 不想去想--但是,尽管如此,完成这些事情的对象代码必须被生成。