Why does Visual Studio not perform return value optimization (RVO) in this case

旧城冷巷雨未停 提交于 2019-11-28 05:42:16

If the code looks like it should be optimized, but is not getting optimized I would submit bug here http://connect.microsoft.com/VisualStudio or raise a support case with Microsoft. This article, although it is for VC++2005 (I couldn't find a current version of document) does explain some scenarios where it won't work. http://msdn.microsoft.com/en-us/library/ms364057(v=vs.80).aspx#nrvo_cpp05_topic3

If we want to be sure the optimization has occurred, one possibility is to check the assembly output. This could be automated as a build task if desired.

This requires generating .asm output using /FAs option like so:

cl test.cpp /FAs

Will generate test.asm.

A potential example in PowerShell below, which can be used in this way:

PS C:\test> .\Get-RVO.ps1 C:\test\test.asm test.cpp
NOT RVO test.cpp - ; 13   :   return Foo(std::move(v));// Expecting RVO to happen here.

PS C:\test> .\Get-RVO.ps1 C:\test\test_v2.optimized.asm test.cpp
RVO OK test.cpp - ; 13   :   return {std::move(v)}; // Expecting RVO to happen here.

PS C:\test> 

The script:

# Usage Get-RVO.ps1 <input.asm file> <name of CPP file you want to check>
# Example .\Get-RVO.ps1 C:\test\test.asm test.cpp
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True,Position=1)]
  [string]$assemblyFilename,

  [Parameter(Mandatory=$True,Position=2)]
  [string]$cppFilename
)

$sr=New-Object System.IO.StreamReader($assemblyFilename)
$IsInReturnSection=$false
$optimized=$true
$startLine=""
$inFile=$false

while (!$sr.EndOfStream)
{
    $line=$sr.ReadLine();

    # ignore any files that aren't our specified CPP file
    if ($line.StartsWith("; File"))
    {
        if ($line.EndsWith($cppFilename))
        {
            $inFile=$true
        }
        else
        {
            $inFile=$false
        }
    }

    # check if we are in code section for our CPP file...
    if ($inFile)
    {
        if ($line.StartsWith(";"))
        {
            # mark start of "return" code
            # assume optimized, unti proven otherwise
            if ($line.Contains("return"))
            {
                $startLine=$line 
                $IsInReturnSection=$true
                $optimized=$true
            }
        }

        if ($IsInReturnSection)
        {
            # call in return section, not RVO
            if ($line.Contains("call"))
            {
                $optimized=$false
            }

            # check if we reached end of return code section
            if ($line.StartsWith("$") -or $line.StartsWith("?"))
            {
                $IsInReturnSection=$false
                if ($optimized)
                {
                    "RVO OK $cppfileName - $startLine"
                }
                else
                {
                    "NOT RVO $cppfileName - $startLine"
                }
            }
        }
    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!