Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 条件断点:此表达式有副作用,将不进行计算_C++_Debugging_Visual Studio 2013 - Fatal编程技术网

C++ 条件断点:此表达式有副作用,将不进行计算

C++ 条件断点:此表达式有副作用,将不进行计算,c++,debugging,visual-studio-2013,C++,Debugging,Visual Studio 2013,我有一个名为size\t a::m()const的非静态const方法,如果它返回的值大于1,我想使用它来触发断点。下面是A类和实例A: class A { public: std::vector<double> myvec; size_t m() const { return myvec.size(); } } a; 但是,当我尝试编译此文件时,我从IDE获得以下消息: 无法设置以下断点: 在myFile.cpp的第xxx行,当'a.m

我有一个名为
size\t a::m()const
的非静态const方法,如果它返回的值大于1,我想使用它来触发断点。下面是
A类
和实例
A

class A
{
public:
    std::vector<double> myvec;
    size_t m() const
    {
      return myvec.size();
    }
} a;
但是,当我尝试编译此文件时,我从IDE获得以下消息:

无法设置以下断点:

在myFile.cpp的第xxx行,当'a.m()>1'为真时

此表达式有副作用,将不进行计算

请注意,
A::m()
不修改任何内容,它只调用向量的
.size()
方法并返回该值,因此表达式具有副作用的断言完全是错误的。事实上,将断点条件替换为
a.myvec.size()>1
(即方法本身的内容)具有相同的效果

关于什么可以用作断点中的条件

条件可以是用户识别的任何有效表达式 调试器

于是我去看了一眼,然后:

产生副作用的一个常见原因是在 调试器窗口。这种评估通常是显而易见的。更多 产生副作用的微妙原因是对性能和其他性能的评估 托管代码中的隐式函数调用

调试器无法判断属性求值是隐式的还是隐式的 函数调用有副作用。因此,默认情况下,调试器 不会自动计算隐式函数调用。财产 默认情况下允许求值,但可以在选项中禁用 对话框。未计算函数调用或属性时 刷新图标出现。您可以通过以下方式手动计算表达式: 单击刷新图标。有关详细信息,请参见如何:刷新手表 价值观

打开属性或隐式函数调用的求值时 禁用时,可以使用ac格式修改器(对于C)强制求值# 仅限)。看


如果有人能把以上段落翻译成英语那就太好了。我是否可以将函数放在这些调试器条件中?

这里是在黑暗中拍摄的,但是您可能希望更深入地了解
const
在方法声明中的用法。您可能希望显式地声明任何不能更改为常量的内容(IIRC const可以在方法声明中的五个不同位置使用,请仔细查看)

const
是编译器强制执行的契约。如果您的方法访问任何非常量的指针,这可能是一个问题。如果存在一个静态变量,则可能会出现问题。还有一种可能是,虽然您的编译器可能很高兴代码中的const很好,但IDE可能没有编译器那么智能(因此可能需要更多的
const
保证)

如果没有代码,就很难确定,但这至少会给你一个想法

有关
const
的更多阅读,本页似乎有一个不错的教程:


以下是我对您提供的帮助链接的翻译:

  • 第1段:调用函数可能有副作用。评估属性可能有副作用
  • 第2段:调试器无法判断是否有副作用,所以我们只假设:“函数=坏”,“属性=好”(即“函数有副作用,属性没有”)。刷新与当前问题无关的图标信息
  • 第3段:想要强制调试器吗?如果您使用的是C#,请在评估后放置
    、ac
因此,归结起来就是,如果你想在求值中调用一个函数,并使用C#,那么在它后面加上
,ac

a->m() > 1,ac

既然你使用C++,我想这归结为“你的评估语句中没有函数!”为了调试,你可以从代码> A::M< /C>中删除const,因为说明符不应该对逻辑流有任何影响。不过,我甚至不确定这是否有效。

评估任何函数调用都会产生副作用,因为它会导致寄存器或堆栈中的状态改变,或者两者都改变。这正是你引用的最后一段所说的

在您的情况下,寄存器和堆栈都会发生更改,假定使用标准项目设置。
call
指令用于调用
m()
,它将指令指针推送到堆栈,返回值存储在
eax
中。除了这两个明显的副作用外,堆栈和寄存器还通过为调用约定
m
生成的序言/尾声进行修改

这可以通过生成裸函数和使用内联汇编程序来验证,内联汇编程序只修改寄存器:

int __declspec(naked) foo()
{
    __asm
    {
        mov eax, 10
        jmp ebx
    }
}

int main()
{
    __asm
    {
        mov ebx, cnt
        jmp foo
    }
cnt:
    return 0;
}

如果您在此应用程序中的任何时候在监视列表中使用
foo()
闯入调试器,它将显示“此表达式有副作用,将不会被计算。”

翻译此语句时有很好的答案,但这里有一个不错的黑客可以使用

在要添加断点的代码中,添加一行,如

auto debug = a.m()
在那里设置断点,您可以在条件中添加此断点

a.m() > 1 // a is an instance of class A
debug > 1
或者你可以这样做

if (a.m() > 1)
    bool debug = 1;

并且可以在调试行中设置断点。

感谢您的响应。我在代码中添加了该方法的内容,它完全是微不足道的,除非
std::vector::size()
修改了某些内容,否则它肯定不会有副作用!如果您返回类似于
(sizet)5的内容,而从不调用size(),会发生什么情况?同样的效果-
此表达式有副作用,不会进行计算。
似乎是VS的问题。如果你能的话,我会在上面写个bug。你不能得到比返回5更多的非副作用y(假设您有一个常量