c++ - 为什么这个未使用的变量没有被优化掉?

标签 c++ gcc clang compiler-optimization

我玩过 Godbolt 的 CompilerExplorer。我想看看某些优化有多好。我的最小工作示例是:

#include <vector>

int foo() {
    std::vector<int> v {1, 2, 3, 4, 5};
    return v[4];
}

生成的汇编器(通过clang 5.0.0,-O2 -std=c++14):

foo(): # @foo()
  push rax
  mov edi, 20
  call operator new(unsigned long)
  mov rdi, rax
  call operator delete(void*)
  mov eax, 5
  pop rcx
  ret

正如大家所见,clang 知道答案,但在返回之前做了很多事情。在我看来,由于“operator new/delete”,甚至创建了 vector 。

谁能向我解释这里发生了什么以及为什么它不返回?

GCC 生成的代码(此处未复制)似乎明确地构造了 vector 。有谁知道 GCC 无法推断结果?

最佳答案

std::vector<T>是一个相当复杂的类,涉及到动态分配。而clang++ is sometimes able to elide heap allocations ,这是一个相当棘手的优化,你不应该依赖它。示例:

int foo() {
    int* p = new int{5};
    return *p;
}
foo():                                # @foo()
        mov     eax, 5
        ret

例如,使用 std::array<T> (不动态分配) produces fully-inlined code :

#include <array>

int foo() {
    std::array v{1, 2, 3, 4, 5};
    return v[4];
}
foo():                                # @foo()
        mov     eax, 5
        ret

作为 Marc Glisse在其他答案的评论中指出,这就是标准在 [expr.new] #10 中所说的:

An implementation is allowed to omit a call to a replaceable global allocation function ([new.delete.single], [new.delete.array]). When it does so, the storage is instead provided by the implementation or provided by extending the allocation of another new-expression. The implementation may extend the allocation of a new-expression e1 to provide storage for a new-expression e2 if the following would be true were the allocation not extended: [...]

关于c++ - 为什么这个未使用的变量没有被优化掉?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47072261/

相关文章:

c++ - 用 c++ 编写一个程序,生成一个带星号的三角形,但结果总是差 2 个数字

c++ - 如何将对象列表从 C++ 传递到 Lua?

ios - 不兼容的指针类型用类型为“BaseClass *”的表达式初始化 'SubClass *__strong'

c++ - 在不同的 C++ 编译器中有通用的解决方案来捕获异常类型被零除,段错误?

c++ - 缩小转换和初始化列表,哪个编译器是对的?

c++ - pcap_dump() 仅对用户降低权限

c++ - 在 decltype 中使用 this 指针

c - 什么时候在 C 中使用 #define 定义静态函数有效?

C++ 不同的错误使用不同的 gcc 优化

gcc - 迭代和取消引用未对齐的内存指针会导致段错误吗? GCC 优化器中的错误?