c++ - 为什么 gcc 与 clang 相比会产生这种奇怪的程序集?

标签 c++ gcc clang

我试图找出 gcc 和 clang 之间的差异以及它们如何处理 std::vector。任何有更多知识的人都可以解释为什么 gcc 和 clang 产生如此不同的输出吗?

海湾合作委员会9.2:https://godbolt.org/z/AFN46d 铿锵9.0:https://godbolt.org/z/kEkpWE

程序:

#include <vector>

int foo(int a) {
    auto vec = std::vector<int>{};
    vec.push_back(1);
    vec.push_back(2);
    return vec[1] * a;
}
int main () {
    return foo(5) + foo(4);
}

clang 产生非常容易理解的汇编。然而,gcc 产生了这种奇怪的东西:

void std::vector<int, std::allocator<int> >::_M_realloc_insert<int>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int&&):
        movabs  rcx, 2305843009213693951
        push    r15
        push    r14
        push    r13
        push    r12
        push    rbp
        push    rbx
        sub     rsp, 24
        mov     r12, QWORD PTR [rdi+8]
        mov     r8, QWORD PTR [rdi]
        mov     rax, r12
        sub     rax, r8
        sar     rax, 2
        cmp     rax, rcx
        je      .L16
        mov     r15, rdx
        mov     rdx, rsi
        mov     rbp, rdi
        mov     r13, rsi
        sub     rdx, r8
        test    rax, rax
        je      .L11
        movabs  r14, 9223372036854775804
        lea     rsi, [rax+rax]
        cmp     rax, rsi
        jbe     .L17

这些神奇的数字从何而来?

最佳答案

GCC 试图保持安全并发出一些额外的检查。您看到的第一个常量仅仅是

__gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(int)

并构成 x86-64 上整数 vector 的最大可能大小。

第二个常数似乎只是

__gnu_cxx::__numeric_traits<ptrdiff_t>::__max

向下舍入以能被 sizeof(int) 整除。

一般来说,这些东西来自 libstdc++ 中的各种 max_size() 方法。 clang 可能能够证明某些检查是不必要的。

关于c++ - 为什么 gcc 与 clang 相比会产生这种奇怪的程序集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60244807/

相关文章:

c++ - Matlab 的 cpp 文件中的矩阵乘法

c++ - System() 的替代方案,用于在程序中运行批处理文件

c - 为什么 sizeof(a) 是 16? (sizeof int 是 4 )

xcode - 什么是 llvm/clang/xcode 的正确版本?

clang - 如何使用 macports 中的 clang-format?

C++ - 在 std::thread 中调用重载函数时编译失败

c++ - 为什么 (false?A() :B()). test() 只有 A 和 B 有子类关系时才能编译?

c++ - 使用 native() boost 路径访问器

gcc - 叮当说 "cstdlib file not found"

c++ - 创建自己签名的 OpenSSL 证书