[英]Conditional breakpoint: This expression has side effects and will not be evaluated
[英]Is there a way around “This expression has side effects and will not be evaluated.”?
在Visual Studio 2017中,我創建了一個調用C ++函數的.natvis調試器可視化規則。
在調試器中,它顯示:
This expression has side effects and will not be evaluated.
除此之外,它還顯示了一個藍色的小箭頭,可以單擊它以強制對其求值,然后它實際上會調用該函數。 (我認為這可能是最近的功能,因為我似乎記得在VS2013中嘗試過此功能,並且不記得它有旁路)
我的問題是:有什么方法可以永久繞過此安全檢查,以便它始終可以立即評估我的功能,而無需我單擊箭頭?
我看過一個非常相似的問題: “此表達會產生副作用,將不會被評估”。 如何抑制? 接受的答案僅對C#有效(在C#表達式的末尾添加ac強制調試器自動重新評估它)
我想如果存在這種情況,它將是以下機制之一:
為了提供有關該應用程序的更多詳細信息:我們在代碼中的各處都使用了uint32,這些字符串是從字符串中哈希出來的,並且只有在開發版本中才加載了字符串數據庫。 解碼功能在二進制搜索樹中查找u32 ID,返回在存儲的節點中找到的字符串。 因此,我知道它是完全無副作用的並且足夠快,以至於不會在每次.natvis規則這樣說時僅調用該函數而影響調試經驗。
經過進一步的研究,我懷疑無法告訴Visual Studio您的函數沒有副作用,甚至對於int MyTestFunction() { return 56; }
無副作用的函數(例如int MyTestFunction() { return 56; }
int MyTestFunction() { return 56; }
仍會在監視窗口中顯示“表達式有副作用,不會被評估”消息。
盡管這不是一個令人滿意的答案,但我確實找到了解決此問題的方法,該方法是使用笨拙,難看的XML語法重新實現我試圖調用的功能(以我的情況為例,通過表進行二進制搜索) .natvis的CustomListItems
標記。
盡管此標簽的名稱暗示它與列表有關,但對於需要某種算法才能實現的任何可視化工具而言,此標簽似乎都是一種包羅萬象的東西。 在<CustomListItems>
您可以使用一堆不同的標記,這些標記可能足以實現幾乎任何算法:
<Variable>
標簽來聲明變量, <Loop>
標記用於迭代, <Break Condition="myCondition">
用於檢查是否終止循環, <Exec>
標記,用於執行表達式,使<Variable>
標記中聲明的變量的值發生變化, <If Condition="myCondition">
用於分支 <Item Name="name">value</Item>
標簽,每個標簽都將在監視窗口中以一行形式顯示在要擴展的變量下方。 據我所知,大多數算法標記只能在CustomListItems
下使用(我嘗試使用一些<Variable>
標記嘗試常規的<Expand>
規則,但出現錯誤,表明它不受支持)
必須重新實現已經以這種可怕的語法運行的C ++函數並不是一件令人愉快的事情(請記住,有些陷阱像必須使用>
和<
代替>
和<
因為它是XML)。
但是,通過以下幾點技巧,它並沒有那么糟糕
<Item>
標記,基本上可以執行“打印調試”的等效操作。 在嘗試使您的.natvis規則起作用時,請使用<Item>
打印出中間值。 如果算法無法正常工作,這將使查找算法失敗的位置變得更加容易。 在工作時刪除這些多余的標簽。 您可以在此處找到文檔和CustomListItems
的示例。
我遇到了同樣的問題,在搜索時遇到了這個問題。
我剛剛找到了一個解決方案,並想在此處發布:如果在XML中將函數定義為“本征”,則編譯器不會顯示類似“ This expression has side effects...
當您調用該內在函數時。
這是一個例子:
我寫了一個自定義字符串類,它是這樣的:
namespace rkstl
{
namespace strings
{
//null-terminated string object consisting of 'char' elements
class string
{
public:
//... c'tors, copy c'tor and d'tor come here
length(); //returns the length of null-terminated string: _mSize
capacity(); //returns the length of the actual buffer: _mCap
clear();
//... other member functions
private:
char* _pStr; //the actual buffer
size_t _mSize; //length of the string
size_t _mCap; //length of the actual buffer
};
//null-terminated wide string object consisting of 'wchar_t' elements
class wstring
{
//...
};
}
}
您可以從我的實現中看到length()
和capacity()
是內在函數。 因此,如果我直接在.XML中調用它們,則編譯器將顯示This expression has side effects...
因此我將必須單擊重新評估按鈕(藍色圓圈箭頭)以查看數據是什么:
<Type Name="rkstl::strings::string">
<DisplayString>{_pStr,na}</DisplayString>
<StringView>_pStr,na</StringView>
<Expand>
<Item Name="[string length]" ExcludeView="simple">length()</Item>
<Item Name="[buffer capacity]" ExcludeView="simple">capacity()</Item>
<ArrayItems>
<Size>_pEnd - _pBegin</Size>
<ValuePointer>_pStr</ValuePointer>
</ArrayItems>
</Expand>
相反,我定義了內部函數來評估與類中相同的事物。 而且我可以直接在.natvis XML中調用它們。 這是我的rkstl::strings::string
.natvis實現:
<Type Name="rkstl::strings::string">
<Intrinsic Name="length_dbg" Expression="(_mSize)"/>
<Intrinsic Name="capacity_dbg" Expression="(_mCap)"/>
<DisplayString>{_pStr,na}</DisplayString>
<StringView>_pStr,na</StringView>
<Expand>
<Item Name="[length of the string]" ExcludeView="simple">length_dbg()</Item>
<Item Name="[capacity of the buffer]" ExcludeView="simple">capacity_dbg()</Item>
<ArrayItems>
<Size>_pEnd - _pBegin</Size>
<ValuePointer>_pStr</ValuePointer>
</ArrayItems>
</Expand>
你可以看到,我定義length_dbg()
和capacity_dbg()
作為內在。 因此,調試器可以安全地調用它們並評估我想要顯示的數據。 結果如下:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.