[英]How can I be sure a routine is taking advantage of (N)RVO?
我想確保我的例程盡可能利用(N)RVO。 除了解析生成的反匯編之外,還有什么我可以做或檢查是否正在使用(N)RVO編譯例程? 在這一點上,我最感興趣的是MSVC和GCC。
不,不是真的。
但是,您可以在編寫代碼時遵循指南。
未命名的返回值優化
即使在調試模式下,每次返回臨時值時都會觸發此操作。
return MyObject(....);
命名返回值優化
每次函數總是返回相同的臨時對象時,這幾乎都會觸發:
MyObject func() {
MyObject result;
if (...) { return result; }
result.push(0);
return result;
}
您可以混合使用這些,但在這種情況下編譯器幾乎不可能應用RVO:
MyObject func() {
MyObject result;
if (...) { return MyObject(...); }
return result;
}
在這里,一個回報可能會受益於RVO而另一個則不受益。 我敢打賭第一個被優化,因為如果你推測性地在返回槽中創建result
並且突然需要采用if
分支,你就會陷入困境。 請注意,只需重新排序語句就可以了:
MyObject func() {
if (...) { return MyObject(...); }
MyObject result;
return result;
}
因此,NRVO的經驗法則是, result
聲明與return result;
之間不應有return
聲明return result;
返回result
本身以外的任何其他語句。
如果你遵循這個,你可以為你贏得賠率。 然后,這只是代碼審查的問題。
並且您還可以使代碼更易於閱讀,因為在知道您確實需要它們之前不會聲明變量!
您可以向析構函數添加調試方法:
struct A
{
~A() { cout << "destructor called"; }
};
A foo()
{
A a;
return a;
}
如果調用析構函數,則可能未應用RVO。
我能想到的可能方法是:
在類中實現引用計數機制,跟蹤通過類創建的實例數,類似於shared_ptr
,這樣就可以檢測正在創建的類的額外副本,如果沒有發生復制省略則刪除。
您可以簡單地將調試跟蹤放在類的復制構造函數和析構函數中,如果沒有發生復制省略,您會看到許多連續的復制構造函數和析構函數調試跟蹤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.