quant
quant

Reputation: 23102

Conditional breakpoint: This expression has side effects and will not be evaluated

I have a non-static const method called size_t A::m() const, which I want to use to trigger a breakpoint if it returns a value greater than 1. Here is class A and instance a:

class A
{
public:
    std::vector<double> myvec;
    size_t m() const
    {
      return myvec.size();
    }
} a;

So I add a breakpoint in Visual Studio 2013 with this condition

a.m() > 1 // a is an instance of class A

However, when I try to compile this I get the following message from the IDE:

The following breakpoint cannot be set:

At myFile.cpp, line xxx, when 'a.m() > 1' is true

This expression has side effects and will not be evaluated.

Note that A::m() does not modify anything, it only calls the .size() method of a vector and returns that value, so the assertion that the expression has side effects is simply false. In fact, replacing the breakpoint condition with a.myvec.size() > 1 (ie. the content of the method itself) has the same effect!

Regarding what can be used as a conditional in a breakpoint, Microsoft says that;

The condition can be any valid expression that is recognized by the debugger.

So I went and had a look at Expressions in the Debugger, and found this:

One common cause of side effects is evaluating a function call in a debugger window. Such evaluations are usually noticeable. A more subtle cause of side effects is the evaluation of properties and other implicit function calls in managed code.

The debugger cannot tell whether a property evaluation or implicit function call has side effects. Therefore, by default, the debugger does not evaluate implicit function calls automatically. Property evaluation is allowed by default, but can be turned off in the Options dialog box. When a function call or property has not been evaluated, a refresh icon appears. You can manually evaluate the expression by clicking the refresh icon. For details, see How to: Refresh Watch Values.

When evaluation of properties or implicit function calls is turned off, you can force evaluation by using the ac format modifier (for C# only). See Format Specifiers in C#.

If someone could translate the above paragraph to English that would be great. Can I put functions in these debugger conditionals or not?

Upvotes: 21

Views: 14659

Answers (4)

Existent
Existent

Reputation: 717

There are good answers translating the statement but here is a nice hack someone could use.

In your code where you want to add break point, add a line such as

auto debug = a.m()

Set a breakpoint there, and you can add this in condition

debug > 1

Or you could do something like this

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

and can set a breakpoint in debug line.

Upvotes: 3

Collin Dauphinee
Collin Dauphinee

Reputation: 13993

Evaluating any function call has side effects, because it induces a change of state, either in registers or the stack, or both. This is exactly what the last paragraph you cited is saying.

In your case, both the registers and stack are changed, assuming standard project settings. A call instruction is used to call m(), which pushes the instruction pointer to the stack, and the return value is stored in eax. On top of these two obvious side effects, the stack and registers are also modified by the prologue/epilogue generated for the calling convention of m.

This can be verified by generating a naked function and using inline assembler, which only modifies registers:

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

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

If you break into the debugger at any point in this application with foo() in your watch list, it will display 'This expression has side effects and will not be evaluated.'

Upvotes: 11

Scott Mermelstein
Scott Mermelstein

Reputation: 15397

Here's my translation of the help link you provided:

  • Paragraph 1: calling functions probably has side effects. Evaluating properties might have side effects.
  • Paragraph 2: the debugger can't tell if there are side effects, so we're just going to assume: "functions = bad", "properties = good" (i.e. "functions have side effect, properties do not"). Refresh icon information that isn't relevant to the immediate issue.
  • Paragraph 3: want to force the debugger? If you're using C#, put ,ac after your evaluation.

So, what it boils down to is, if you want to call a function in your evaluation and are using C#, put ,ac after it

a->m() > 1,ac

Since you're using C++, I think this boils down to "No functions in your evaluation statements for you!" For the purpose of debugging, you possibly can remove the const from A::m, since the specifier doesn't (shouldn't) have any impact on the logic flow. I'm not even sure if that will work, though.

Upvotes: 11

Dan L
Dan L

Reputation: 325

Shot in the dark here, but you might want to look at the use of const in your method declaration in more depth. You might want to explicitly state anything that is not to be changed into a const (IIRC correctly const can be used in five different locations in a method declaration so look carefully).

const is a contract that the compiler enforces. If your method accesses any pointer that is not const, it might be a problem. If there is a static variable that might be a problem. It's also possible that while your compiler might be happy that const is fine in your code the IDE might not be as intelligent as the compiler (and thus might want some more const assurance).

Without your code, it's kind of hard to tell for sure, but this should give you at least an idea.

For some more reading on const, this page seems to have a decent tutorial:

http://www.cprogramming.com/tutorial/const_correctness.html

Upvotes: 1

Related Questions