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

后端 未结 1 861
广开言路
广开言路 2020-12-08 06:41

I was answering a question and recommending return by-value for a large type because I was confident the compiler would perform return-value optimization (RVO). But then it

相关标签:
1条回答
  • 2020-12-08 07:18

    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"
                    }
                }
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题