【问题标题】:Visual Studio fails to display some watched expressionsVisual Studio 无法显示一些被监视的表达式
【发布时间】:2009-11-24 08:38:04
【问题描述】:

在 Visual Studio 中,由于各种原因,我的大部分对象和变量都无法在调试会话期间解析。这意味着我无法检查或观察对象或它们调用它们的函数,这使得调试我的代码变得非常困难,因为我的大多数表达式根本不起作用。向监视窗口添加表达式时遇到的一些典型错误包括:

  • CXX0019:错误:类型转换错误
  • CXX0059:错误:左操作数是类而不是函数名
  • CXX0058:错误:未找到重载运算符

这些表达式通常涉及重载运算符和/或模板类对象。

为什么会这样?你是怎么解决的?

【问题讨论】:

  • 你能发表一些表达吗?使用具有复杂算法(运算符)的监视窗口正在自找麻烦

标签: c++ visual-studio debugging expression


【解决方案1】:

您遇到的错误是由于调试器的限制造成的,不存在 Daniel 所暗示的错误。

监视窗口不能调用重载的运算符。 如果你有例如std::vector<int> vecSomething 你不能将vecSomething[0] 放入监视窗口,因为std::vector<int>::operator[] 是一个重载的运算符。因此,对于对象向量,您不能在监视窗口中执行vecObject[0].SomeMemberVariableOfObject。你可以写vecObject._Myfirst[0].SomeMemberVariableOfObject。在 Visual Studio 的 STL 实现中,_Myfirst 是指向第一个元素的向量的成员。

如果您将自己的变量和类型添加到监视窗口,请直接将监视添加到数据成员。像member.memberStruct.ptrToObj->memberOfObj 这样的指针链是没有问题的。

编辑:

其实Visual Studio可以在Watch窗口调用代码: http://geekswithblogs.net/sdorman/archive/2009/02/14/visual-studio-2008-debugging-ndash-the-watch-window.aspx

因此,为什么不能使用重载运算符有点神秘。

【讨论】:

  • @stijn:你能详细说明一下吗?它确实评估表达式,即您可以观看“(a+b)/2”,它确实评估代码以按照 autoexp.dat 中给出的规则格式化表达式,但是它何时执行我的代码?
  • @stijn:更新了我的帖子。我发现你是对的,在监视窗口中调用函数是允许的。我不知道。
  • 我记得我曾在监视窗口中“千载难逢”地评估重载的运算符函数,但大多数情况下它们肯定不会评估。
【解决方案2】:

为什么会这样?

该工具有其局限性。例如,很多时候我“去定义”并没有找到定义。我必须“在文件中查找”。在调试会话期间也不会计算某些表达式也就不足为奇了。

你是怎么解决的?

  • 保持表达式简单。不要 直接连接它们,使用 具有解释性名称的变量 中间结果。
  • 使用显式断言支持您的代码。如果它是“错误的”,则断言应该失败。

【讨论】:

  • 我不记得了,C++ 中有原生的断言运算符吗?还是必须自己设计?此外,您认为将包装函数编写为常用检查表达式的接口以解决此调试器限制是否可行?这会产生更多的编程开销,但我目前还想不出更好的方法。
  • @Jonny assert 是一个宏。它通常由编译器供应商定义。是的,编写额外的函数将有助于弄清楚发生了什么。
【解决方案3】:

Microsoft Documentation 中准确描述了问题和可能的解决方法

调试器接受大多数 Microsoft 和 ANSI C/C++ 表达式;但是,您确实需要注意以下事项:

不支持的运算符和其他运算符

对原生 C++ 表达式的限制

【讨论】:

  • 谢谢,但是我注意到 VS2008 的文档似乎是错误的:它说重载 operator[]() 会起作用,但是为变量 vector<int> v 添加手表 v[42] 会出现 CXX0058 错误-- 即使将42 更改为42U42L42LU 以满足参数精确类型匹配的要求。也许它不起作用w.r.t。模板?
  • @j_random_hacker 可能是模板的原因,我不知道,因为我没用过VS2008。当[] 操作符在监视窗口中不起作用时,您可以显示向量类的内部成员并添加偏移量以查看您想查看的数据,但这比输入v[42] 慢很多。跨度>
  • 链接文档适用于 managed C++。即 C++/CLI。不同的评估器,不同的支持功能。它与原始问题无关。装箱和属性在 C++ 中甚至不作为一流的概念存在。从链接页面,您可以找到正确的本机代码文档。 docs.microsoft.com/en-us/previous-versions/visualstudio/…
  • @Adam 我更改了链接。
【解决方案4】:

我找到了一种解决方案,它(在某种程度上)解决了重载运算符的问题。它似乎不依赖于类的内部结构。您必须使用操作员调用的扩展形式。这是vector<int> v 的示例:

v.operator[](0)

我在 Visual C++ 2012 中对其进行了测试。

【讨论】:

  • 在 VS2010 中操作员调用地图时说:'CX0039: Error: symbol is ambiguous'
【解决方案5】:

PDB 文件管理远非完美,尤其是在大型项目中。特别是,VS 具有合并 VSxx.PDB 中的所有符号的相当愚蠢的行为,即使跨不同项目也是如此。 /Fd 开关可以轻松解决此问题;传递$(TargetDir)$(TargetName).pdb 或类似的东西。

【讨论】:

    【解决方案6】:

    这可能是由于嵌套类
    示例:

    A级 { B类 { 诠释我; }; };

    像 (B*)(0x12345678) 这样的转换会失败,但 (A::B*)(0x12345678) 会成功

    【讨论】:

      猜你喜欢
      • 2018-10-04
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多