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
,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代码>(假设您有一个常量