MSVC 不会展开简单的 for 循环:我错过了什么?

xuh*_*dev 5 c++ visual-c++

在下面的代码片段中,两个函数执行完全相同的功能并且在逻辑上是等效的。

constexpr char a[] = {50, 100};

bool contains_loop(char num) {
    for (int i = 0; i < 2; ++ i) {
        if (a[i] == num) {
            return true;
        }
    }
    return false;
}

bool contains_expanded(char num) {
    return num == a[0] || num == a[1];
}
Run Code Online (Sandbox Code Playgroud)

我在godbolt中的测试表明,在/O2打开的 x64 MSVC 19.30 中,contains_loop未针对展开进行优化。汇编代码中,仍然有计数器,而编译后的汇编代码中没有contains_expanded

        inc     rax
        cmp     rax, 2
Run Code Online (Sandbox Code Playgroud)

在 gcc 中-O3,它们被编译为完全相同的汇编代码。

这种优化看起来非常简单,但我无法让 MSVC 对其进行优化(自动)。我在这里缺少什么?

Joe*_*Joe 2

我基本上是在重写这个答案,因为我错误地拨打了电话contains_expanded,而不是contains_loop您所询问的电话。

简短的回答是,即使使用 VS2022(真实的东西)和 /O2 和 /Oi,循环显然也没有展开。我什至尝试了支持大小而不是支持速度,结果是相同的。

我用了这个基本的主要

int main()
{
    std::vector<char> vals { 50, 49};
    std::cout << "Test" << std::endl;
    for (auto v : vals)
    {
        const auto val = contains_expanded(v);
        std::cout << "Contains = " << v << std::boolalpha << val;
    }                   
}
Run Code Online (Sandbox Code Playgroud)

我的编译优化开关使用/O2 和/Oi。这是输出命令 tlog 文件中的编译行

^C:\USERS\JMOLE\SOURCE\REPOS\TESTCPP\TESTCPP\TESTCPP.CPP
/c /Zi /nologo /W3 /WX- /diagnostics:column /sdl /O2 /Oi /GL /D NDEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /permissive- /Fo"X64\RELEASE\\" /Fd"X64\RELEASE\VC143.PDB" /external:W3 /Gd /TP /FC C:\USERS\JMOLE\SOURCE\REPOS\TESTCPP\TESTCPP\TESTCPP.CPP
Run Code Online (Sandbox Code Playgroud)

这是我的版本中的调用列表contains_loop

    const auto val = contains_loop(v);
00007FF7234D1224  xor         eax,eax  
00007FF7234D1226  cmp         byte ptr [rax+r15],bl  
00007FF7234D122A  je          main+0AAh (07FF7234D123Ah)  
00007FF7234D122C  inc         rax  
00007FF7234D122F  cmp         rax,2  
00007FF7234D1233  jl          main+96h (07FF7234D1226h)  
00007FF7234D1235  xor         sil,sil  
00007FF7234D1238  jmp         main+0ADh (07FF7234D123Dh)  
00007FF7234D123A  mov         sil,1  
Run Code Online (Sandbox Code Playgroud)

因此,无论您选择什么优化,循环都不会在 MSVC 中展开。如果你错过了什么,我不知道它是什么