Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何让MSVC编译器优化多步骤POD初始化?_C++_Optimization_Visual C++_C++17_Clang++ - Fatal编程技术网

C++ 如何让MSVC编译器优化多步骤POD初始化?

C++ 如何让MSVC编译器优化多步骤POD初始化?,c++,optimization,visual-c++,c++17,clang++,C++,Optimization,Visual C++,C++17,Clang++,我制作了以下示例代码: #include <vector> struct POD { int a; int b; int c; inline static POD make_pod_with_default() { POD p{ 41, 51, 61 }; return p; } inline void change_pod_a(POD &p, int a) { p.

我制作了以下示例代码:

#include <vector>

struct POD {
    int a;
    int b;
    int c;

    inline static POD make_pod_with_default()
    {
        POD p{ 41, 51, 61 };
        return p;
    }

    inline void change_pod_a(POD &p, int a) {
        p.a = a;
    }

    inline void change_pod_b(POD &p, int b) {
        p.b = b;
    }

    static POD make_pod_with_a(int a) {
        POD p = make_pod_with_default();
        p.change_pod_a(p, a);
        return p;
    }

    static POD make_pod_with_b(int a) {
        POD p = make_pod_with_default();
        p.change_pod_b(p, a);
        return p;
    }
};

int main()
{
    std::vector<POD> vec{};
    vec.reserve(2);
    vec.push_back(POD::make_pod_with_a(71));
    vec.push_back(POD::make_pod_with_b(81));
    return vec[0].a + vec[0].b + vec[0].c + vec[1].a + vec[1].b + vec[1].c;
}
71有一个到[esp+32]的mov,但41的到[esp+32]的mov仍然存在,没有用!我怎样才能为MSVC编写代码来实现这种优化,MSVC是否能够做到这一点

GCC和CLANG都提供了更优化的版本,但CLANG以一种非常干净和合乎逻辑的方式在没有开销的情况下大获全胜:

生成的代码:

main: # @main
push rax
mov edi, 24
call operator new(unsigned long)
mov rdi, rax
call operator delete(void*)
mov eax, 366
pop rcx
ret
所有操作都是在编译时完成的,即71+51+61+41+81+61=366!
我必须承认,看到我的程序在编译时被计算,但仍然在程序集中调用vec.reserve()是一件痛苦的事情。。。但到目前为止,叮当声仍然拿着蛋糕!来吧,MSVC,这不是一个volatile向量。

如果你打开你的方法
constexpr
,你可能会:

constexpr POD step_one()
{
    POD p{2, 5, 11};
    p.b = 3;
    return p;
}

constexpr void step_two(POD &p)
{
    p.c = 5;
}

constexpr POD make_pod(){
    POD p = step_one();
    step_two(p);
    return p;
}

POD make_pod_final()
{
    constexpr POD res = make_pod();
    return res;
}
导致:

make_pod_final PROC
    mov      eax, DWORD PTR $T1[esp-4]
    mov      DWORD PTR [eax], 2
    mov      DWORD PTR [eax+4], 3
    mov      DWORD PTR [eax+8], 5
    ret      0

较短的复制器:
POD make_POD(){POD p=POD{0,1,2};p.c=3;返回p;}
。在这种形式下,MSVC可以通过改变
POD p=POD{0,1,2}来优化它
POD p={0,1,2}。不确定当初始化器是函数调用的结果时是否有类似的解决方法。我相信您的意思是“将POD p=POD{0,1,2};更改为POD p={0,1,3};”。问题是,这个示例是我设计的精简版本。我有多步骤初始化的可读性和设计原因:一些步骤在以后被调用,或者从未被调用。我在我的示例中包括了一个您建议的优化示例,这样每个人都可以从中分辨出与我需要的不同不是我的意思。将其更改为
podp={0,1,2}并保留
p.c=3赋值后,MSVC确实可以对其进行优化。当然,如果实际程序中的第二步是有条件调用的,或者是在其他中间函数调用后调用的,那么这种优化在这种情况下可能是不可能的。@hvd我已经发现了差异,所以对于MSVC,“A={…};”与“A=A{}”不同这是一个很好的尝试,它很聪明,对我的其他东西也很有帮助,所以非常感谢你!但我的吊舱是在巨大的容器中动态分配的:(这一实现非常重要,我明天将编辑我的问题以更好地表示我的问题。我现在更清楚地知道我需要什么:我需要一个调用其他函数的函数,这些函数是内联的,以便再次优化。这是第二次优化。MSVC可以做到吗?我正在安装带有MSVC集成的CLANG另一种选择,但我宁愿继续使用MSVC编译器…你不会相信CLANG编译的是什么…:“mov eax,9 pop rcx ret”LMAO!
make_pod_final PROC
    mov      eax, DWORD PTR $T1[esp-4]
    mov      DWORD PTR [eax], 2
    mov      DWORD PTR [eax+4], 3
    mov      DWORD PTR [eax+8], 5
    ret      0