簡體   English   中英

有沒有辦法解決“此表達式有副作用,將不會被評估。”?

[英]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強制調試器自動重新評估它)

我想如果存在這種情況,它將是以下機制之一:

  1. 注冊表設置或其他始終禁用安全檢查的全局設置。
  2. 一種注釋代碼或.natvis規則的方法,以便編譯器以某種方式知道它是安全且無副作用的純函數

為了提供有關該應用程序的更多詳細信息:我們在代碼中的各處都使用了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 ++函數並不是一件令人愉快的事情(請記住,有些陷阱像必須使用&gt;&lt;代替><因為它是XML)。

但是,通過以下幾點技巧,它並沒有那么糟糕

  • 如果您在Visual Studio中編輯.natvis文件,則保存該文件將觸發調試器重新評估顯示,而無需重新啟動程序,因此對.natvis規則進行迭代非常快。 (注意:從外部編輯器編輯.natvis文件時,這在VS2017中對我似乎不起作用)
  • 在規則中使用大量的<Item>標記,基本上可以執行“打印調試”的等效操作。 在嘗試使您的.natvis規則起作用時,請使用<Item>打印出中間值。 如果算法無法正常工作,這將使查找算法失敗的位置變得更加容易。 在工作時刪除這些多余的標簽。

您可以在此處找到文檔和CustomListItems的示例。

https://msdn.microsoft.com/zh-CN/library/jj620914.aspx

我遇到了同樣的問題,在搜索時遇到了這個問題。

我剛剛找到了一個解決方案,並想在此處發布:如果在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM