Ответ 1
Если код выглядит так, как он должен быть оптимизирован, но не оптимизирован, я бы добавил ошибку здесь http://connect.microsoft.com/VisualStudio или поднимет случай поддержки с Microsoft. Эта статья, хотя для VС++ 2005 (я не мог найти текущую версию документа) объясняет некоторые сценарии, когда это не сработает. http://msdn.microsoft.com/en-us/library/ms364057(v=vs.80).aspx#nrvo_cpp05_topic3
Если мы хотим убедиться, что оптимизация произошла, одна из возможностей - проверить выход сборки. Это может быть автоматизировано как задача сборки, если это необходимо.
Для этого требуется генерация вывода .asm с использованием опции /FAs:
cl test.cpp /FAs
Будет генерировать test.asm.
Потенциальный пример в PowerShell ниже, который можно использовать следующим образом:
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>
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"
}
}
}
}
}